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

时间:2013-02-11 20:45:19

标签: c++ oop class pointers inheritance

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"
}

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

3 个答案:

答案 0 :(得分:7)

您可以使用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,则在这种情况下(因为不涉及虚拟继承),您甚至可以使用{{1}因为它是在编译时执行的,所以会产生较少的开销。

static_cast<>

答案 1 :(得分:3)

您必须抛弃继承层次结构。您的案例是根据适当的类型使用dynamic_cast量身定制的,因为如果您尝试实际投射的对象具有预期类型,则允许您以类型安全的方式签入。

答案 2 :(得分:1)

在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子句内部,如果我们使用if并且使用else if并且使用{{1}}进行多个连续的dynamic_cast,则通常会更方便。 {{1}}&#39; S