private inheritance - c++

I dont completely understand this:
class Base
{
public:
Base()
{
cout<<"Base" << endl;
}
virtual void call()
{
cout<<"Base call" << endl;
}
};
class Derived: private Base
{
public:
Derived()
{
cout<<"Derived" << endl;
}
};
int main(void)
{
Base *bPtr = new Derived(); // This is not allowed
}
Is it because someone might call call() using bPtr which is actually done on derived object? Or is there any other reason?

Public inheritance means that everyone knows that Derived is derived from Base.
Protected inheritance means that only Derived, friends of Derived, and classes derived from Derived know that Derived is derived from Base.*
Private inheritance means that only Derived and friends of Derived know that Derived is derived from Base.
Since you have used private inheritance, your main() function has no clue about the derivation from base, hence can't assign the pointer.
Private inheritance is usually used to fulfill the "is-implemented-in-terms-of" relationship. One example might be that Base exposes a virtual function that you need to override -- and thus must be inherited from -- but you don't want clients to know that you have that inheritance relationship.
*also: how much wood would a woodchuck chuck...

From a common understanding of inheritance, C++’ “private inheritance” is a horrible misnomer: it is not inheritance (as far as everything outside of the class is concerned) but a complete implementation detail of the class.
Seen from the outside, private inheritance is actually pretty much the same as composition. Only on the inside of the class do you get special syntax that is more reminiscent of inheritance than composition.
There’s a caveat though: C++ syntactically treats this as inheritance, with all the benefits and problems that this entails, such as scope visibility and accessibility. Furthermore, C-style casts (but no C++ cast!) actually ignores visibility and thus succeeds in casting your Derived pointer to Base:
Base* bPtr = (Base*) new Derived();
Needless to say, this is evil.

Because private means "implementation detail", which makes the fact that Derived derives from Base an implementation detail.
Private inheritance is not interface inheritance, but implementation inheritance. It doesn't implement an "Is-A" relationship, but an "Is-Implemented-Using" relationship. Derived isn't a Base as far as users of the classes are concerned, it just happens to (currently) be implemented using it.

If you inherit privately any code that requires the conversion from Derived* to Base* must be a member or a friend of the Derived class.

http://www.parashift.com/c++-faq-lite/private-inheritance.html

With private inheritance, you lose the option to treat your derived object as an object of your base class.

Related

Inheritance with incomplete base class

I've a question regarding a concept. First, I'm a mechanical engineer and not a programmer, thus I have some C++ knowledge but not much experience. I use the finite element method (FEM) to solve partial differential equations.
I have a base class Solver and two child linSolver, for linear FEM, and nlinSolver for non-linear FEM. The members and methods that both children share are in the base class. The base class members are all protected. Thus using inheritance makes the child classes "easy to use", like there weren't any inheritance or other boundaries. The base class itself, Solver, is incomplete, meaning only the children are of any use to me.
The concept works actually pretty good - but I think that having an unusable class is a bad design. In addition I read that protected inheritance is not preferred and should be avoided if possible. I think the last point don't really apply to my specific use, since I will never use it allow and any attempt to do so will fail (since it is incomplete).
The questions are:
Is it common to use inheritance to reduce double code even if the base class will be unusable?
What are alternatives or better solutions to such a problem?
Is protected inheritance really bad?
Thank you for your time.
Dnaiel
Having "unusable" base classes is actually very common. You can have the base class to define a common interface usable by the classes that inherits the base-class. And if you declare those interface-functions virtual you can use e.g. references or pointers to the base-class and the correct function in the inherited class object will be called.
Like this:
class Base
{
public:
virtual ~Base() {}
virtual void someFunction() = 0; // Declares an abstract function
};
class ChildA : public Base
{
public:
void someFunction() { /* implementation here */ }
};
class ChildB : public Base
{
public:
void someFunction() { /* other implementation here */ }
};
With the above classes, you can do
Base* ptr1 = new ChildA;
Base* ptr2 = new ChildB;
ptr1->someFunction(); // Calls `ChildA::someFunction`
ptr2->someFunction(); // Calls `ChildB::someFunction`
However this will not work:
Base baseObject; // Compilation error! Base class is "unusable" by itself
While the (working) example above is simple, think about what you could do when passing the pointers to a function. Instead of having two overloaded functions each taking the actual class, you can have a single function which takes a pointer to the base class, and the compiler and runtime-system will make sure that the correct (virtual) functions are called:
void aGlobalFunction(Base* ptr)
{
// Will call either `ChildA::someFunction` or `ChildB::someFunction`
// depending on which pointer is passed as argument
ptr->someFunction();
}
...
aGlobalFunction(ptr1);
aGlobalFunction(ptr2);
Even though the base-class is "unusable" directly, it still provides some functionality that is part of the core of how C++ can be (and is) used.
Of course, the base class doesn't have to be all interface, it can contain other common (protected) helper or utility functions that can be used from all classes that inherits the base class. Remember that inheritance is a "is-a" relationship between classes. If you have two different classes that both "is-a" something, then using inheritance is probably a very good solution.
You should check the concept of Abstract class.
It's designed to provide base class that cannot be instantiated.
To do so you provide at least one method in the base class like this
virtual void f()=0;
Each child have to override the f function (or any pure virtual function from the base class) in order to be instantiable.
Don't think of the BaseClass as a class in its own right, but as an interface contract and some implementation help. Therefore, it should be abstract, if neccessary by declaring the dtor pure virtual but providing an implementation anyway. Some OO purists may frown upon any non-private element, but purity is not a good target.

How to call derived class method in private inheritance?

Below code is not compiling for me...
class Base
{
public:
Base(){}
virtual void Display()
{
cout << "Base Display" << endl;
}
};
class Derived : private Base
{
private:
void Display() override
{
cout << "Derived Display" << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Derived d;
d.Display();
Derived* dp = new Derived();
dp->Display();
delete dp;
return 0;
}
Compiler reporting errors when I am calling Derived::Display(). How to call it?
What kind of problems we can solve by writing code like this?
You can't access a private method from outside the class. Hence the compilation error.
You are mixing two different concepts here, the access specifier of the member function and the access specifier of the base class.
You cannot call the member function because its access specifier is private and you are attempting to call from a function that is not a friend. That is regardless of the type of inheritance from Base or even if that relationship exists.
The access specifier in the inheritance relationship determines what parts of the code can consider your type to be a Base and which cannot. In this particular case, inside Derived and its friends you can use a reference or pointer to Derived as if it was a Base, but not outside of it.
How to call it? What kind of problems we can solve by writing code like this?
Private inheritance models implemented in terms of, and can be used to provide some functionality through the use of a third party library/class hierarchy from which your own type need not conceptually derive. Avoiding the public inheritance inhibits your users from seeing you as the base, which is intentional as that is a detail of implementation. Inside your own type, you can use the inheritance relationship:
void detail(Base *base) {
base->Display(); // Base::Display is public
}
void Derived::show() { // Derived::show is public:
detail(this); // Private inheritance is visible inside Derived
}
You've made Display private in the derived class, so it's accessible via a pointer/reference to Base, but not directly in a Derived object, nor via a reference/pointer to Derived.
// This should work:
Base *b = new Derived;
b->Display();
// and so should this:
Derived d;
Base &b = d;
b.Display();
...but either of these would also require public inheritance to allow implicit conversion from Derived to Base.
You can't call a derived class method with private inheritance out side of class it become private even if it's defined as public.
Private inheritance hides every method and attribute from outer world, thus your Derived instances on heap or stack cannot call Display directly like you did in your main function. You can replace private with public to avoid these kind of errors or use a pointer to Base to access hidden base methods.
Edit: Improved with suggestion by Jerry.
Private inheritance creates a "contains-a" relationship (it is effectively like creating a member variable of the type Base). What you are attempting to do is create an "is-a" relationship, which is done through public inheritance.

private inheritance in C++

I am learning the concepts of OOPS, and came across private inheritance. From what I've learnt - When a class derives from a base class and letter when the derived class is instantiated, the constructor of the Base class is called first, followed by the constructor of the derived class. So, in the code "A created" would be printed first.
The problem is since the inheritance is private, all the members of A would be private inside B, so how can the constructor of A be called when B is instantiated. Going by this logic, the following code should generate errors, but when I run it, it compiles fine, and gives the output "A created" followed by "B created".
How is this happening? Or am I making some mistake in understanding the concept?
#include <iostream>
using namespace std;
class A{
public:
A(void)
{
cout<<"A created"<<endl;
}
~A()
{
//do nothing
}
void doSomething(void)
{
cout<<"hi";
}
};
class B:private A
{
public:
B(void)
{
cout<<"B created"<<endl;
}
~B()
{
//do nothing
}
};
int main() {
B* myptr = new B();
//myptr->doSomething();
delete myptr;
return 0;
}
B can call public (and protected) methods of A, since A constructor is public B can call it.
Please see following link to better understand c++ private inheritance:
Difference between private, public, and protected inheritance
The access specifier for inheritance limits access to code outside the derived class; think to the base class A as if it were a normal private field:" the outside" can't see it, but B can use it freely from "the inside".
As for the constructor, it's implicitly called by B's constructor, so there's no problem (and, besides, otherwise private inheritance would be unusable).
Still, don't worry too much about private inheritance, it's useful in extremely rare cases (I've never seem it actually used in real life, and for this reason many languages don't even support it), normally composition (using a normal private field) is a better and simpler way.
Here is good short article about private inheritance which illustrates in details what is private inheritance, when it is useful and when it should be avoided in favour of inclusion.
In short:
Inheritance access modifier limits access to basic class properties and methods not for derived class but for code which uses derived class.
This is useful to 'replace' (not 'extend') basic class interface for users of inherited class.
In general it's considered better to include basic class member rather than use private inheritance.
If you need to reuse some methods of basic class which rely on virtual functions and you need to override virtual functions (but you still want to hide part of basic class interface from external code), this is more appropriate case for private inheritance.
Hope this will help.

More methods in derived classes than base class

I would like to ask a question about programming style in this case of derived class:
class A
{
public:
virtual foo1()=0;
}
class B: public A
{
public:
virtual foo1();
virtual foo2();
}
class C: public A
{
public:
virtual foo1();
}
int main() {
B mB();
C mC();
mB.foo2() //OK!
mC.foo2() // obviously, it is not correct
return 0;}
Therefore, should a derived class have less or equal public methods than the abstract base class?
If the derived classes require more methods, should these be private?
Derived classes will almost always have more public functions than base classes. This is the point of inheritance: you can define an abstract base class which only outlines the basic behavior of a variable, then derived classes can expand upon this basic behavior for specific cases.
An inherited class is always a specialization of the base class. It implements more specific functions (and usually more functions all together). In you're example, you're expecting two different specializations to behave the same way outside of the behavior defined by the base class. (foo2 is not defined in A). That's where the problem lies. If you need to define common behavior outside of A, the solution would be to create an intermediate class.
class Intermediate : public A
{
public:
virtual foo1()=0;
virtual foo2()=0;
}
class B: public Intermediate
{
public:
virtual foo1();
virtual foo2();
}
Now any class which can implement foo2 should extend Intermediate, and any function which requires functionality foo2 should ask for a variable with at least type Intermediate.
There is nothing wrong with this class structure. There is nothing wrong with a derived class having more methods than the parent class-- it's quite commonplace. The line mC.foo2(); is just wrong, and that is not the fault of the classes.
A derived class must at least implement ALL abstract methods from the base class. This is the minimum. If you do add other methods, members or whatever is up to you.
But it would be not very smart to derive from the class and add nothing, because this is not what inheritance is for (at least IS-A-relationships). If you go for private inheritance it might be different.
In nearly ALL projects I've worked on, we have had baseclasses that have less functionality than the derived class - in extreme cases, the baseclass may even just have nearly no functionality, but the derived class has dozens of functions and a half a dozen member variables.
This is exactly what derived classes are meant to do.
Obviously, you need to KNOW what kind of derived class you have, and only use the derived classes "extra" functions when they are available.

Private Inheritance and Derived Object to Base reference

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?
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).
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).