C ++从基类指针访问派生类成员

时间:2010-03-12 21:48:19

标签: c++ inheritance pointers derived-class

如果我分配类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?

5 个答案:

答案 0 :(得分:56)

不,您无法访问derived_int,因为derived_int属于Derived,而basepointerBase的指针。

你可以反过来这样做:

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

答案 1 :(得分:10)

你在这里的雷区跳舞。基类永远不会知道它实际上是派生的实例。最安全的方法是在基础中引入虚函数:

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指向Derived以外的其他内容,您的程序将会死亡,这是预期的结果。

或者,您可以使用dynamic_cast<Derived>(basepointer)。但是你需要在Base中至少有一个虚函数,并准备遇到零。

static_cast<>,就像一些人的建议,是一种可靠的方法来射击自己。不要为“不安全的C语言家族”的恐怖故事做出贡献。

答案 2 :(得分:7)

您可以使用CRTP

你基本上在模板中使用派生类作为基类

答案 3 :(得分:4)

通过让基类知道派生类的类型是可能的。这可以通过使基类成为派生类型的模板来完成。这个C ++习语称为curiously recurring template pattern

知道派生类,基类指针可以静态转换为指向派生类型的指针。

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();
}

答案 4 :(得分:0)

//如果您知道要使用的派生类

Derived * derivedpointer = dynamic_cast&lt;派生*&gt; basepointer;

//然后您可以使用derivedpointer

访问派生类