10

假设我们有这个代码

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;
}

main 函数中的 C 风格转换不能正确地用 C++ 转换 ( static_cast, dynamic_cast, reinterpret_cast) 表示。但是首先允许这样做的原因是什么?它不会伤害封装吗?

更新 这不是链接问题的重复,因为这个问题是关于 C++ 中的设计决策。它不问我能用这种语言做什么或不能做什么,它问为什么会做出某些决定。

4

3 回答 3

8

当在指向基类和派生类的指针之间使用 C 风格的指针转换时,它的行为类似于static_cast- 即使基类是私有的。

(不相关的指针类型之间的 C 风格转换是reinterpret_casts)。

该标准说:

执行的转换

— 一个 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 时,即使基类不可访问,转换也是有效的

— 指向派生类类型对象的指针或派生类类型的左值或右值可以分别显式转换为指向明确基类类型的指针或引用;

— 指向派生类类型成员的指针可以显式转换为指向明确的非虚拟基类类型成员的指针;

— 指向明确非虚拟基类类型对象的指针、明确非虚拟基类类型的左值,或指向明确非虚拟基类类型成员的指针可以显式转换为指针,引用或指向派生类类型成员的指针。

您的情况在第一点中描述,因此转换完成static_cast并调整指针。

于 2012-05-26T21:52:15.970 回答
1

这是因为在 C 中,允许使用此强制转换将任何指针转换为任何其他指针,并且 C++ 尝试尽可能地与 C 兼容,但在涉及到类时试图做好正确的工作,所以 C 风格cast 比reinterpret_cast这种情况下要强。

于 2012-05-26T21:55:30.823 回答
-1

C 风格的转换允许您将任何类型转换为任何其他类型。如果你愿意,你可以这样做(std::istream*)&c,但不建议这样做。

于 2012-05-26T21:52:35.377 回答