繁体   English   中英

使用指向基本abstact类的指针访问子类成员

[英]Accessing child class members using pointer to a base abstact class

class a //my base abstract class
{
public:
virtual void foo() = 0;
};

class b : public a //my child class with new member object
{
public:
void foo()
{}
int obj;
};

int main()
{
b bee;
a * ptr = &bee;
ptr->obj; //ERROR: class a has no member named "obj"
}

我的问题是,当我有一个指向子类(“a”)指向子类(“b”)对象的指针时,如何访问“obj”成员? 我知道铸造应该成功,但我正在寻找更好的解决方案。

您可以使用dynamic_cast<>运算符的指针转换为a的指针b 只有当ptr指向的对象的运行时类型为b ,转换才会成功,否则将返回空指针,因此您必须在转换后检查结果:

b* p = dynamic_cast<b*>(ptr);
if (p != nullptr)
{
    // It is safe to dereference p
    p->foo();
}

如果你可以保证ptr所指向的对象的类型是b ,但是,在这种情况下(因为不涉及虚拟继承)你甚至可以使用static_cast<> ,这会产生较少的开销,因为它是在编译时执行的-时间。

b* p = static_cast<b*>(ptr);
// You are assuming ptr points to an instance of b. If your assumption is
// correct, dereferencing p is safe
p->foo();

你必须抛弃继承层次结构。 您的案例是为了将dynamic_cast用于适当的类型而量身定制的,因为如果您尝试实际投射的对象具有预期类型,则允许您以类型安全的方式进行检查。

在GCC和Clang(以及我认为的Visual Studio中),您还可以使用以下语法糖

if (Derived* x = dynamic_cast<Derived*>(x)) {
     // do something with \c x now that we know its defined     
}

而在C ++ 11中,使用auto类型推理,甚至更好

if (auto x = dynamic_cast<Derived*>(x)) {
     // do something with \c x now that we know its defined     
}

最后,如果我们想限制为只读访问

if (const auto x = dynamic_cast<Derived*>(x)) {
     // read something from \c x now that we know its defined     
}

请注意,这很好地限制的范围x到if语句(S),如果我们一个后做多个连续的dynamic_cast这往往是更方便使用的另一个里面if的和else if的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM