向下转型和虚函数

Downcasting and Virtual Functions

我在面试中被问到这个问题,我不确定以下情况下的行为:

class A 
{ 
      virtual fun1(){...}
      virtual fun2(){...}
};

class B : public A
{ 
      virtual fun1(){...}
      virtual fun2(){...}
};

现在如果,

A* AObj = new A;
B* BObj = (B*) AObj;

BObj 是因为 virtual 关键字可以访问 B 的方法,还是因为它指向 AObj 的对象?

有人可以帮助我了解向下转型对访问的影响吗?

在这种情况下(多态)指针的类型(BObj,这里它的类型不是B)是它指向的对象的类型(A)。 所以 BObj 是 Base class 的对象并且 不能做派生 class (B) 中定义的额外工作 (函数)。

首先,这样做

A* AObj = new AObj();

B* BObj = AObj;

一点也不安全,因为它把一个base-class对象(Parent)的地址赋值给一个派生的class(Child)指针。因此,代码期望 base-class 对象具有派生的 class 属性。

但是你可以这样做:

    A* AObj = new AObj();

    B* BObj = dynamic_cast<B*>AObj;

这将检查 Aobj 是否可以分配给 Bobj。它return是对象的地址,如果可以,否则会return0.

因此您可以像这样使用它:

B* BObj = dynamic_cast<B*>AObj;
if(BObj)
{
    //Now you can use it safely.
}

将基class 对象的地址分配给派生class 指针是undefined behavior。所以任何事情都可能发生:调用 BObj 的函数可以调用 B 的函数,可以调用 A 的函数,可以使程序崩溃,甚至可以格式化硬盘。这将完全取决于编译器及其优化选项。