涉及私人继承的C风格的向上和向下倾斜

Abh*_*hay 6 c++ inheritance casting

请考虑以下代码: -

class A {};

class B : private A {};

B* bPtr1 = new B;
// A* aPtr1 = bPtr1; // error
// A* aPtr2 = static_cast<A*>(bPtr1); // error
A* aPtr3 = (A*)bPtr1;
B* bPtr2 = (B*)aPtr3;
Run Code Online (Sandbox Code Playgroud)

C样式转换丢弃了私有继承,而隐式和static_cast失败(也dynamic_cast).为什么?如果C风格的强制转换只是一点点,那么C++强制转换是如何实现的,即它们如何知道内存占用的继承类型?

在将bPtr1转换为aPtr3之后,我将不得不再使用另一个C风格的转换向下转换为B static_cast并且dynamic_cast失败.那么,bPtr2保证是好的吗?

提前致谢

j_r*_*ker 7

5.4.7中的标准规定,C风格的强制转换实际上可以做的比任何新式强制转换的序列都要多 - 特别是包括从指针到派生到指针到基类的转换,即使基类是无法访问,这正是私有继承所发生的事情.(为什么这应该被允许,特别是为什么它应该只允许C风格的演员阵容,完全超出我的范围;但无可否认这是允许的.)

因此,运行是正确的,即使B从多个基类继承,编译器也必须正确处理OP的C风格指针转换.我自己用MSVC++ 8和MinGW测试证实自己在实践中的结果-当B从多个基类继承,编译器将转换时调整指针B*A*,反之亦然,以便正确的对象或子对象被识别.

我坚持认为,如果你打算将a 作为一个B 公开,你应该公开推导,因为使用私有继承而不是必须使用C风格的演员表.ABA


rlb*_*ond 0

C++ 强制转换是由编译器(而不是链接器)强制执行的。这并不是因为私有继承导致了不同的类布局;而是因为私有继承导致了不同的类布局。如果继承不是公共的,基于类的声明,编译器将禁止您将指向派生类的指针转换为指向其基类的指针。