C++ 从基类指针访问派生类成员
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2436125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ Access derived class member from base class pointer
提问by Peter
If I allocate an object of a class Derived
(with a base class of Base
), and store a pointer to that object in a variable that points to the base class, how can I access the members of the Derived
class?
如果我分配一个类的对象Derived
(基类为Base
),并将指向该对象的指针存储在指向基类的变量中,我如何访问Derived
该类的成员?
Here's an example:
下面是一个例子:
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?
回答by Peter Alexander
No, you cannot access derived_int
because derived_int
is part of Derived
, while basepointer
is a pointer to Base
.
不,您无法访问,derived_int
因为derived_int
是 的一部分Derived
,而basepointer
是指向 的指针Base
。
You can do it the other way round though:
你可以反过来做:
Derived* derivedpointer = new Derived;
derivedpointer->base_int; // You can access this just fine
Derived classes inherit the members of the base class, not the other way around.
派生类继承基类的成员,而不是相反。
However, if your basepointer
was pointing to an instance of Derived
then you could access it through a cast:
但是,如果您basepointer
指向的是一个实例,Derived
那么您可以通过强制转换访问它:
Base* basepointer = new Derived;
static_cast<Derived*>(basepointer)->derived_int; // Can now access, because we have a derived pointer
Note that you'll need to change your inheritance to public
first:
请注意,您需要public
先将继承更改为:
class Derived : public Base
回答by Seva Alekseyev
You're dancing on the minefield here. The base class can never know that it's actually an instance of the derived. The safest way to do that would be to introduce a virtual function in the base:
你正在这里的雷区跳舞。基类永远无法知道它实际上是派生类的一个实例。最安全的方法是在基类中引入一个虚函数:
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;
If basepointer
points as something other that a Derived
, your program will die horribly, which is the intended result.
如果basepointer
指向 a 以外的东西Derived
,你的程序会死得很惨,这就是预期的结果。
Alternatively, you can use dynamic_cast<Derived>(basepointer)
. But you need at least one virtual function in the Base
for that, and be prepared to encounter a zero.
或者,您可以使用dynamic_cast<Derived>(basepointer)
. 但是Base
为此您至少需要一个虚函数,并准备好遇到零。
The static_cast<>
, like some suggest, is a sure way to shoot yourself in the foot. Don't contribute to the vast cache of "unsafety of the C language family" horror stories.
的static_cast<>
,像一些建议,就是搬起石头砸自己的脚的可靠方法。不要对“C 语言家族的不安全性”恐怖故事的大量缓存做出贡献。
回答by kirill_igum
回答by Pawe? Bylica
It is possible by letting the base class know the type of derived class. This can be done by making the base class a template of derived type. This C++ idiom is called curiously recurring template pattern.
通过让基类知道派生类的类型是可能的。这可以通过使基类成为派生类型的模板来完成。这个 C++ 习惯用法称为奇怪的重复模板模式。
Knowing the derived class, the base class pointer can be static-casted to a pointer to derived type.
知道派生类,基类指针可以静态转换为指向派生类型的指针。
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();
}
回答by Roger Wang
//if you know what derived class you are going to use
//如果你知道你将使用哪个派生类
Derived* derivedpointer = dynamic_cast < Derived * > basepointer;
派生* 派生指针 = dynamic_cast < 派生 * > 基指针;
//then you can access derived class using derivedpointer
//然后你可以使用派生指针访问派生类