Why does C style cast allow you to convert to a private base class? [duplicate]

蓝咒 提交于 2019-11-27 18:18:10

问题


This question already has an answer here:

  • Can I cast a derived class to a private base class, using C-style cast? 3 answers

Say we have this code

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

The C style cast in the main function cannot be correctly expressed in terms of the C++ casts (static_cast, dynamic_cast, reinterpret_cast). But what is the reason to allow this in the first place? Doesn't it hurt encapsulation?

UPDATE This is not a duplicate of the linked question, because this question is about design decisions in C++. It does not ask what I can or cannot do with the language, it asks why certain decisions might have been made.


回答1:


When a C-style pointer cast is used between pointers to a base and derived class, it behaves like a static_cast - even if the base is private.

(C-style casts between unrelated pointer types are reinterpret_casts).

The Standard says:

The conversions performed by

— a const_cast (5.2.11),

— a static_cast (5.2.9),

— a static_cast followed by a const_cast,

— a reinterpret_cast (5.2.10), or

— a reinterpret_cast followed by a const_cast,

can be performed using the cast notation of explicit type conversion. The same semantic restrictions and behaviors apply, with the exception that in performing a static_cast in the following situations the conversion is valid even if the base class is inaccessible:

— a pointer to an object of derived class type or an lvalue or rvalue of derived class type may be explicitly converted to a pointer or reference to an unambiguous base class type, respectively;

— a pointer to member of derived class type may be explicitly converted to a pointer to member of an unambiguous non-virtual base class type;

— a pointer to an object of an unambiguous non-virtual base class type, a glvalue of an unambiguous non-virtual base class type, or a pointer to member of an unambiguous non-virtual base class type may be explicitly converted to a pointer, a reference, or a pointer to member of a derived class type, respectively.

Your situation is described in the first point, so the conversion is done by static_cast and the pointer is adjusted.




回答2:


It's because in C it was allowed to convert any pointer to any other pointer using this cast and C++ tries to be C-compatible as much as possible, but tries to do a good job to be correct when it comes to classes, so C style cast is stronger than reinterpret_cast in this situation.




回答3:


A C-style cast allows you to convert any type to any other type. You can do (std::istream*)&c if you'd like, but it's not recommended.



来源:https://stackoverflow.com/questions/10770044/why-does-c-style-cast-allow-you-to-convert-to-a-private-base-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!