#include <iostream>
struct B1 {
char x[1];
};
struct B2 {
char x[1];
};
struct D :
private B1,
private B2 {
char x[1];
};
#define RAW_PTR static_cast<const void*>
int main()
{
using namespace std;
D d;
D* pd = &d;
cout << "-------" << endl;
cout << "upcasts" << endl;
cout << "-------" << endl;
cout << endl;
{
//B2* p = pd; // error: 'B2' is an inaccessible base of 'D'
}
{
//B2* p = static_cast<B2*>(pd); // error: 'B2' is an inaccessible base of 'D'
}
{
B2* p = reinterpret_cast<B2*>(pd); // Compiles, but is wrong!
// simply copies bits, doesn't adjust
cout << "reinterpret_cast:" << endl;
cout << pd << endl;
cout << p << endl;
cout << ((RAW_PTR(p) == RAW_PTR(pd)) ? "Wrong!" : "Right.") << endl;
cout << endl;
}
{
B2* p = (B2*)pd; // Correct conversion, here equivalent to
// implicit conversion ignoring 'private' access specifier;
// makes the needed adjustment
cout << "C-style cast:" << endl;
cout << pd << endl;
cout << p << endl;
cout << ((RAW_PTR(p) == RAW_PTR(pd)) ? "Wrong!" : "Right.") << endl;
cout << endl;
}
cout << endl;
B2* pb2 = (B2*)&d; // (correct conversion)
cout << "---------" << endl;
cout << "downcasts" << endl;
cout << "---------" << endl;
cout << endl;
{
//D* p = pb2; // error: invalid conversion from 'B2*' to 'D*' [-fpermissive]
// (then also error: 'B2' is an inaccessible base of 'D')
}
{
//D* p = static_cast<D*>(pb2); // error: 'B2' is an inaccessible base of 'D'
}
{
D* p = reinterpret_cast<D*>(pb2); // Compiles, but is wrong!
// simply copies bits, doesn't adjust
cout << "reinterpret_cast:" << endl;
cout << pb2 << endl;
cout << p << endl;
cout << ((RAW_PTR(p) == RAW_PTR(pb2)) ? "Wrong!" : "Right.") << endl;
cout << endl;
}
{
D* p = (D*)pb2; // Correct conversion, here equivalent to
// static_cast ignoring 'private' access specifier;
// makes the needed adjustment
cout << "C-style cast:" << endl;
cout << pb2 << endl;
cout << p << endl;
cout << ((RAW_PTR(p) == RAW_PTR(pb2)) ? "Wrong!" : "Right.") << endl;
cout << endl;
}
}