6
class a //my base abstract class
{
public:
virtual void foo() = 0;
};

class b : public a //my child class with new member object
{
public:
void foo()
{}
int obj;
};

int main()
{
b bee;
a * ptr = &bee;
ptr->obj; //ERROR: class a has no member named "obj"
}

私の質問は、子クラス( "b")オブジェクトを指す基本クラス( "a")へのポインターがある場合、どうすれば "obj"メンバーにアクセスできますか?キャスティングでうまくいくはずですが、もっと良い解決策を探しています。

4

3 に答える 3

8

演算子を使用して、ポインターをへのdynamic_cast<>ポインターに変換できます。が指すオブジェクトの実行時の型が である場合にのみ変換が成功し、それ以外の場合はnull ポインターを返すため、変換後に結果を確認する必要があります。abptrb

b* p = dynamic_cast<b*>(ptr);
if (p != nullptr)
{
    // It is safe to dereference p
    p->foo();
}

ptrただし、が指すオブジェクトの型が であることを保証できる場合b、この場合 (仮想継承が含まれないため) を使用することもできますstatic_cast<>。これは、コンパイル時に実行されるため、オーバーヘッドが少なくなります。

b* p = static_cast<b*>(ptr);
// You are assuming ptr points to an instance of b. If your assumption is
// correct, dereferencing p is safe
p->foo();
于 2013-02-11T20:50:54.087 に答える
3

継承階層をキャストダウンする必要があります。dynamic_castあなたのケースは、実際にキャストしようとしているオブジェクトが期待されるタイプであるかどうかをタイプセーフな方法でチェックできるように、適切なタイプを使用するために調整されています。

于 2013-02-11T20:47:01.693 に答える
1

GCC と Clang (および Visual Studio だと思います) では、次のシンタックス シュガーも使用できます。

if (Derived* x = dynamic_cast<Derived*>(x)) {
     // do something with \c x now that we know its defined     
}

C++11 では、auto型推論を使用すると、さらに優れています

if (auto x = dynamic_cast<Derived*>(x)) {
     // do something with \c x now that we know its defined     
}

最後に、読み取り専用アクセスに制限したい場合

if (const auto x = dynamic_cast<Derived*>(x)) {
     // read something from \c x now that we know its defined     
}

これにより、 の範囲がxif 句の内部にifうまく制限されることに注意してくださいelse if

于 2013-08-17T21:58:57.677 に答える