向下转型和虚函数
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
的函数,可以使程序崩溃,甚至可以格式化硬盘。这将完全取决于编译器及其优化选项。
我在面试中被问到这个问题,我不确定以下情况下的行为:
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
的函数,可以使程序崩溃,甚至可以格式化硬盘。这将完全取决于编译器及其优化选项。