Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C-Style upcast and downcast involving private inheritance

Consider the following piece of code :-

class A {};

class B : private A {};

B* bPtr1 = new B;
// A* aPtr1 = bPtr1; // error
// A* aPtr2 = static_cast<A*>(bPtr1); // error
A* aPtr3 = (A*)bPtr1;
B* bPtr2 = (B*)aPtr3;

The C-style cast discards the private inheritance while both the implicit and static_cast fail (also dynamic_cast). Why ? If C-style casts are just bit-fiddling, how are C++ casts implemented i.e. how do they know the type of inheritance from memory footprint?

After bPtr1 is casted to aPtr3, i will have to use another C-style cast to downcast to B as again both static_cast and dynamic_cast fail. So, is bPtr2 guaranteed to be good?

Thanks in advance

like image 967
Abhay Avatar asked May 10 '09 06:05

Abhay


People also ask

What is upcast and downcast in C++?

Upcasting can cause object slicing when a derived class object is passed by value as a base class object, as in foo(Base derived_obj). Downcasting. The opposite process, converting a base-class pointer (reference) to a derived-class pointer (reference) is called downcasting.

Why is Static_cast better than C-style cast?

In short: static_cast<>() gives you a compile time checking ability, C-Style cast doesn't. static_cast<>() is more readable and can be spotted easily anywhere inside a C++ source code, C_Style cast is'nt. Intentions are conveyed much better using C++ casts.

What is the difference between Static_cast and Dynamic_cast?

static_cast − This is used for the normal/ordinary type conversion. This is also the cast responsible for implicit type coersion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc. dynamic_cast −This cast is used for handling polymorphism.

Does C have Static_cast?

Static casts are only available in C++. Static casts can be used to convert one type into another, but should not be used for to cast away const-ness or to cast between non-pointer and pointer types.


1 Answers

The standard states in 5.4.7 that C-style casts can actually do more than any sequence of new-style casts can do -- specifically including casting from a pointer-to-derived to pointer-to-base even when the base class is inaccessible, which is precisely what happens here with private inheritance. (Why this should be allowed, and in particular why it should be allowed only for C-style casts, is utterly beyond me; but it's undeniably allowed.)

So dribeas is right, compilers are obliged to handle the OP's C-style pointer conversion correctly, even when B inherits from multiple base classes. My own testing with MSVC++8 and MinGW confirms his results in practice -- when B inherits from multiple base classes, the compiler will adjust pointers when converting a B* to an A* or vice versa so that the correct object or subobject is identified.

I stand by my assertion that you ought to derive B publicly from A if you ever intend to treat a B as an A, since using private inheritance instead necessitates using C-style casts.

like image 79
j_random_hacker Avatar answered Oct 07 '22 17:10

j_random_hacker