Why does C style allow you to convert to a private base class?

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

C styles in the main function cannot be correctly expressed in terms of C ++ translations ( static_cast , dynamic_cast , reinterpret_cast ). But what is the reason for this in the first place? Does encapsulation hurt?

UPDATE This is not a duplicate of the related question, because this question is about design decisions in C ++. He does not ask what I can or cannot do with the language, he asks why some decisions could be made.

+7
source share
3 answers

This is 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 right when it comes to classes, so in this case the C style is stronger than reinterpret_cast .

+1
source

When, when specifying a C style pointer between pointers to the base and derived classes, it behaves like a static_cast - even if the base is private.

(C-style is discarded between unrelated pointer types reinterpret_cast s).

The standard says:

Conversions Performed

- const_cast (5.2.11),

- static_cast (5.2.9),

- static_cast followed by const_cast,

- reinterpret_cast (5.2.10) or

- reinterpret_cast followed by const_cast,

can be performed using an explicit type conversion letter. The same semantic restrictions and behavior apply, except that when static_cast is executed in the following situations, the conversion is valid even if the base class is not available :

- a pointer to an object of a derived type of a class, or an lvalue or rvalue of a type of a derived class, can be explicitly converted to a pointer or a reference to a unique type of the base class, respectively;

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

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

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

+7
source

A cast in C style allows you to convert any type to any other type. You can do (std::istream*)&c if you want, but this is not recommended.

-one
source

All Articles