说我们有这个代码
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 ++中的设计决策。它没有问我能用或不能用语言做什么,它询问为什么可能做出某些决定。
答案 0 :(得分:7)
当在指向基类和派生类的指针之间使用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除外即使基类不可访问,转换也有效:
- 指向派生类类型的对象或派生类类型的左值或右值的指针可以分别显式转换为指针或对明确基类类型的引用;
- 指向派生类类型成员的指针可以显式转换为指向非明确的非虚基类类型成员的指针;
- 指向明确的非虚基类类型的对象的指针,明确的非虚基类类型的glvalue,或指向非明确的非虚基类类型成员的指针可以显式转换为指针,引用或指向派生类类型成员的指针。
您的情况在第一点中描述,因此转换由static_cast
完成并且指针已调整。
答案 1 :(得分:1)
这是因为在C中允许使用此转换将任何指针转换为任何其他指针,并且C ++尝试尽可能地与C兼容,但是当涉及到类时,尝试做好工作是正确的,所以在这种情况下,C样式演员比reinterpret_cast
强。
答案 2 :(得分:-1)
C风格的演员表允许您将任何类型转换为任何其他类型。如果您愿意,可以(std::istream*)&c
,但不建议这样做。