C++ //练习 19.3 已知存在如下的继承体系,其中每个类分别定义了一个公有的默认构造函数和一个虚析构函数:
C++ Primer(第5版) 练习 19.3
练习 19.3 已知存在如下的继承体系,其中每个类分别定义了一个公有的默认构造函数和一个虚析构函数:
class A { /* ... */ };
class B: public A { /* ... */ };
class C: public B { /* ... */ };
class D: public B, public A { /* ... */ };
下面哪个dynamic_cast将失败?
( a ) A *pa = new C;B *pb = dynamic_cast<B*>(pa);
( b ) B *pb = new B;C *pc = dynamic_cast<C*>(pb);
( c ) A *pa = new D;B *pb = dynamic_cast<B*>(pa);
环境:Linux Ubuntu(云服务器)
工具:vim
代码块
//正确
( a ) A *pa = new C;B *pb = dynamic_cast<B*>(pa);
//失败,pb 是指向 B 的指针,我们试图将其转换为指向 C 的指针。
//由于 B 与 C 不具有多态关系(即,C 派生自 B,但并非所有 B 对象都是 C 对象),
//因此此 dynamic_cast 将失败并返回 nullptr。此转换将失败。
( b ) B *pb = new B;C *pc = dynamic_cast<C*>(pb);
//失败,pa 是指向 A 的指针,但实际上指向类型 D 的对象。D 从 A 和 B 继承(通过不同的路径)。
//B *pb = dynamic_cast<B*>(pa); pa 是指向 A 的指针,但它指向的对象 (D) 也派生自 B。
// 由于 D 派生自 B,因此此转换可能会成功。但是,dynamic_cast 需要确定 D 中正确的 B 子对象。
//鉴于 A 是两个不同继承路径的一部分(一次是直接继承,一次是通过 B),除非涉及虚拟继承,
//否则 dynamic_cast 可能会因歧义而失败。此转换可能会失败,
//具体取决于类的设计方式以及是否使用虚拟继承来解决歧义。如果没有虚拟继承,转换可能会因歧义而失败。
( c ) A *pa = new D;B *pb = dynamic_cast<B*>(pa);
