>假设我们有这段代码
class A {
public:
A() : x(1) {}
virtual ~A() {}
int x;
};
class B {
public:
B() : y(2) {}
virtual ~B() {}
void g()
{
cout << "B::" << y << endl;
}
int y;
};
class C : private A, private B {
public:
void f()
{
B* p = static_cast<B*>( this );
p->g();
}
};
int main()
{
C c;
((B*)&c)->g();
return 0;
}
主函数中的 C 样式转换不能用C++转换(static_cast
、dynamic_cast
、reinterpret_cast
)正确表示。但是,首先允许这样做的原因是什么?封装不疼吗?
更新这不是链接问题的重复,因为此问题是关于C++中的设计决策的。它没有问我能或不能用语言做什么,它问为什么会做出某些决定。
指向基类和派生类的指针之间使用 C 样式指针转换时,它的行为类似于static_cast
- 即使基是私有的。
(不相关的指针类型之间的 C 样式转换reinterpret_cast
s)。
该标准说:
执行的转换
— const_cast (5.2.11),
— static_cast (5.2.9),
— 一个static_cast后跟一个const_cast,
— reinterpret_cast (5.2.10),或
— 一个reinterpret_cast后跟一个const_cast,
可以使用显式类型转换的强制转换表示法来执行。相同的语义限制和行为适用,但以下情况在执行static_cast时,即使基类不可访问,转换也是有效的:
— 指向派生类类型的对象的指针或派生类类型的左值或右值可以分别显式转换为指向明确基类类型的指针或引用;
— 指向派生类类型成员的指针可以显式转换为指向明确非虚拟基类类型成员的指针;
— 指向明确非虚拟基类类型的对象的指针、明确非虚拟基类类型的 GL值或指向明确非虚拟基类类型成员的指针可以分别显式转换为指针、引用或指向派生类类型成员的指针。
您的情况在第一点中描述,因此转换由static_cast
完成,指针进行调整。
这是因为在 C 中允许使用此强制转换将任何指针转换为任何其他指针,并且C++尝试尽可能与 C 兼容,但在涉及类时尝试做好正确的工作,因此在这种情况下 C 样式强制转换比 reinterpret_cast
更强。
C 样式强制转换允许您将任何类型转换为任何其他类型。 如果您愿意,可以执行(std::istream*)&c
,但不建议这样做。