45

Derivedあるクラス(の基本クラス)のオブジェクトを割り当て、Baseそのオブジェクトへのポインターを基本クラスを指す変数に格納すると、どのようにDerivedクラスのメンバーにアクセスできますか?

次に例を示します。

class Base
{
    public:
    int base_int;
};

class Derived : public Base
{
    public:
    int derived_int;
};

Base* basepointer = new Derived();
basepointer-> //Access derived_int here, is it possible? If so, then how?
4

5 に答える 5

78

いいえ、は の一部であり、は へのポインタであるderived_intため、アクセスできません。derived_intDerivedbasepointerBase

ただし、逆の方法で行うこともできます。

Derived* derivedpointer = new Derived;
derivedpointer->base_int; // You can access this just fine

派生クラスは基本クラスのメンバーを継承しますが、その逆ではありません。

ただし、basepointerのインスタンスを指している場合はDerived、キャストを介してアクセスできます。

Base* basepointer = new Derived;
static_cast<Derived*>(basepointer)->derived_int; // Can now access, because we have a derived pointer

public継承を最初に変更する必要があることに注意してください。

class Derived : public Base
于 2010-03-12T21:52:11.883 に答える
12

あなたはここの地雷原で踊っています。基本クラスは、それが実際に派生のインスタンスであることを知ることはできません。これを行う最も安全な方法は、ベースに仮想関数を導入することです。

class Base 
{ 
protected:
 virtual int &GetInt()
 {
  //Die horribly
 }

public: 
 int base_int; 
}; 

class Derived : Base 
{ 
  int &GetInt()
  {
    return derived_int;
  }
public: 
int derived_int 
}; 

basepointer->GetInt() = 0;

basepointerが a 以外のものを指している場合Derived、プログラムは恐ろしく死んでしまいます。これは意図した結果です。

または、 を使用することもできますdynamic_cast<Derived>(basepointer)。ただし、そのためには少なくとも 1 つの仮想関数が必要でありBase、ゼロに遭遇する準備ができています。

static_cast<>、一部の人が示唆しているように、足を撃つ確実な方法です。「C 言語ファミリの危険性」に関するホラー ストーリーの膨大なキャッシュに貢献しないでください。

于 2010-03-12T21:54:10.287 に答える
10

CRTPを使用できます

基本的に、基本クラスのテンプレートで派生クラスを使用します

于 2012-10-09T07:12:23.863 に答える
7

基底クラスに派生クラスの型を知らせることで可能です。これは、基本クラスを派生型のテンプレートにすることで実行できます。この C++ のイディオムは、不思議な繰り返しテンプレート パターンと呼ばれます。

派生クラスがわかれば、基本クラスのポインターを派生型へのポインターに静的キャストできます。

template<typename DerivedT>
class Base
{
public:
    int accessDerivedField()
    {
        auto derived = static_cast<DerivedT*>(this);
        return derived->field;
    }
};


class Derived : public Base<Derived>
{
public:
    int field;
};

int main()
{
    auto obj = new Derived;
    obj->accessDerivedField();
}
于 2014-09-10T11:06:43.267 に答える