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

时间:2009-05-10 06:18:16

标签: 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;

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

将bPtr1转换为aPtr3之后,我将不得不使用另一个C风格的转换向下转换为B,因为static_castdynamic_cast都失败了。那么,bPtr2保证是好的吗?

提前致谢

4 个答案:

答案 0 :(得分:7)

5.4.7中的标准规定C风格的强制转换实际上可以比任何新风格的强制转换更多地执行 - 具体包括从指针派生到指针的转换即使基类是不可访问的,也可以使用私有继承。 (为什么这应该被允许,特别是为什么它只应该被允许进行C风格演员表演,完全超出我的范围;但无可否认地允许这样做。)

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

如果您打算将B视为A,我会坚持认为您应该B 公开来自A因为使用私有继承而不是需要使用C风格的强制转换

答案 1 :(得分:0)

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

答案 2 :(得分:-1)

现有答案很棒,但您可能会发现一些有用的信息与此有关:

  

C风格的演员阵容只是一点点摆弄

如果在两个指针类型之间使用旧式强制转换,编译器通常不需要使用任何位。您告诉编译器您要将内存位置视为包含某种类型(因为您知道它实际上有效),因此编译器在运行时根本不执行任何操作来修改内存的内容。转换只是在编译时禁用类型安全。

答案 3 :(得分:-4)

  

如果C风格的强制转换只是一点点,那么C ++强制转换是如何实现的,即他们如何知道内存占用的继承类型呢?

C ++中的C风格演员意味着不仅仅是眼睛。从技术上讲,它们是要求编译器选择转换所需的正确转换运算符的唯一方法。出于同样的原因,这比使用reinterpret_cast更好。后者是实现定义。

似乎围绕C风格的演员阵容存在很多混乱。请记住,在您知道如何使用它之前,没有任何工具是安全的。这同样适用于C风格的演员表。进行C风格演员的要点是要求编译器为给定的一对类型选择最安全和最便携的转换。这可能会触发从static_castreinterpret_cast的静默更改并引入错误。关键是:你需要知道自己在做什么。