Reputation: 659
As far as I understand the reason that we cannot pass a derived class object to a base class reference for private inheritance is that Since Derived is privately inherited from Base, the default constructor of Base would be called before the constructor of Derived. But because it is private and not inherited to Derived, we get a compiler error.
But, if I try to create a public constructor for Base and inherit from Derived privately and then re-assign the public status to Base's constructor will it allow me to pass a derived's instance to Base reference?
I tried it as follows,
#include <iostream>
using namespace std;
class base
{
public:
base(){}
void print(){ puts("In base"); }
};
class derived : private base
{
public:
base::base; /* Throws an error - Declaration doesnt declare anything*/
void print(){ puts("In derived"); }
};
void func(base& bRef)
{
}
int main()
{
derived dObj;
func(dObj); /* Throws an error - 'base' is an inaccessible base of derived */
}
It throws an error for base::base (publicizing privately inherited constructor to public). Is what I am trying valid? Can anyone please tell me?
Upvotes: 1
Views: 1047
Reputation: 437386
The reason we cannot have a base class reference to a derived object that inherits privately is because that would violate the Liskov Substitution Principle: the derived object IS-NOT-A base class object because it does not provide the base class public interface. You cannot work around this
For this reason, private inheritance is a way of reusing implementation and not when you want to make a more specialized type. As this can most of the time be done with composition (i.e. having a member of the base class instead of privately deriving), private inheritance might be a bad code smell.
You can read here (be sure to follow all the links) for more information on when private inheritance is a good option (summary: when there simply is no other choice).
Upvotes: 4
Reputation: 12212
No, it is not valid to point to an object of Derived with a pointer or reference of Base class. If it were possible, then the whole purpose of private inheritance (hide the fact that the derived class inherits part (or the whole) of its functionality from the base class) would be useless.
Say you have a method foo()
in the base class. You don't want this method to be called. But if it were possible to point the object from a pointer of the base class, then it would also be possible to call foo()
.
Base * ptrBase = &objDerived; // Let's suppose this would compile
ptrBase->foo(); // Now we can call foo() (?)
When you declare private inheritance, is as if the Derived class where not related to the base class. It is just you, the developer, the only one that should "know" that this relationship exist, and actually you should forget about it, because it just won't work.
Private inheritance is just there solely as a reusability mechanism, not as a true inheritance mechanism. It is not recommended to even use it, since you can obtain a better result by simply applying composition (i.e. just make an attribute of class Base in Derived).
Upvotes: 2