Search code examples
c++castingreinterpret-cast

Why reinterpret_cast does work in private inhertiance


I was reading about access specifiers when applying inheritance, and I know that in private inheritance we could not cast from a derived to a base class using pointers/references.

But when I used reinterpret_cast it worked. below is my test code:

class base {
int _a;
public: 
    base(int a): _a(a) {}
    base(): _a(0) {}
};

class derived : private base
{
public:
    derived(int b):base(b) {};  
};

int main() {

    derived b(25); 
    base &a = static_cast<base&>(b);//this line will generate a compile error
    base &c = reinterpret_cast<base&>(b);  //here it works 
}

So my question is even doing private inheritance, why the base class would be exposed using retinterpret_cast ?

Thank you!

//EDIT 2

class base {
    int _a; 
public:         
    base(int a): _a(a) {}
    base(): _a(100) {}  
    ~base() { std::cout << "deleting base" << _a << "\n"; }
};

class derived : private base
{
public:
    virtual ~derived() = default;
    derived(int b):base(b) {};
};

int main() {

    derived b(25); 
    base &c = reinterpret_cast<base&>(b); 
}

//OutPut : Deleting 25

Solution

  • Is private inheritance violated? Not really.

    Accessibility in C++ only affects in what scopes can an identifier be used to refer to something in a valid fashion. The system is designed to protect against Murphy, not a Machiavellian trick like you use.

    reinterpret_cast is basically you telling the compiler "forget what you know, trust my judgment instead". So it does. You claim this lvalue does in fact refer to a base? Fine, have it your way. But the compiler isn't gonna do anything to protect you, it assumes you know what you are doing. It can break quite easily. There's @Dani's example, and there's this one:

    class derived : private base
    {
    public:
        virtual ~derived() = default;
        derived(int b):base(b) {};  
    };
    

    What do you think will happen if you try to use c and call a member function that uses _a? What will it find instead?