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_int它是 的一部分Derivedbasepointer而是指向 的指针Base

你可以反过来做:

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

派生类继承基类的成员,而不是相反。

但是,如果您basepointer指向的实例Derivedthen 您可以通过强制转换访问它:

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). 但是你至少需要一个虚函数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 回答
1

//如果你知道你要使用什么派生类

Derived* derivedpointer = dynamic_cast < Derived * > basepointer;

//然后你可以使用派生指针访问派生类

于 2017-02-17T17:13:58.180 回答