如果我分配类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?
答案 0 :(得分:56)
不,您无法访问derived_int
,因为derived_int
属于Derived
,而basepointer
是Base
的指针。
你可以反过来这样做:
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
访问派生类