Private Inheritance and Derived Object to Base reference - c++

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

Related

Does base class destructor need to be virtual if only some derived classes are polymorphic?

I have a similar situation to this question where I have 2 classes that share a public interface function, and so I've pulled that function (manage_data_in_memory() in the example) out into a base class which the 2 classes inherit from. However, the 2 classes are otherwise not related, and one of them is polymorphic, whereas the other one isn't. It is also not expected for someone to declare an object of this base class, as it exists only to prevent code duplication (is there a way to enforce this? I know pure virtual functions can prevent an object from being instantiated, but declaring a dummy pure virtual that does nothing in the derived class seems like bad design).
Does the base class destructor need to be virtual in this case? This would force the other derived class to also have a virtual destructor, which it doesn't need.
Thanks.
So now I have code in the form
class base { // don't instantiate an object of this, is there a way to enforce this?
public:
void manage_data_in_memory();
protected:
data;
};
class derived : public base
{
public:
void sendData();
private:
virtual void sendDataHelper(); // override this in derived classes which need to send custom data in addition to the default data
};
class derived2 : public base
{
public:
void do_Z_On_data()
};
The destructor of a base class must be virtual if and only if an instance of a derived class will be destroyed through a pointer to the base object. If the destructor isn't virtual in such case, then the behaviour of the program would be undefined. Example:
struct Base {
// ...
};
struct Derived : Base {};
std::unique_ptr<Base> ptr = std::make_unique<Derived>();
// Base::~Base must be virtual
It's possible to prevent the user of the class from doing this (at least by accident) by using private inheritance. If the destructor isn't virtual, then inheritance should be private except possibly in special cases where you need a standard layout class.
is this because private inheritance would make the destructor private
No, private inheritance doesn't make destructor private.
which prevents anyone from declaring an object of Base?
No, and declaring an object of Base isn't a problem.
Private inheritance prevents conversion from derived pointer into a base pointer outside the member functions of the derived class (and friends). The inability acquire a pointer to base of the derived class would prevent the user from deleting a derived object through such pointer.

What can possible use of making a class friend and inheriting it also?

I was going through one of my local libraries and noticed the follwowing:
class Derived : public Base
{
friend class Base; // serves as a factory
protected:
pthread_spinlock_t allocLock;
bool isSafe{ true };
Derived();
char *funcA() override;
public:
void funcB( bool _in ) override;
virtual ~Derived();
};
I am not able to understand if Base has been inherited then why it has been made a friend of Derived. Also how the comment serves as a factory make sense here?
If it were to access Base function, :: operator would have been sufficient.
Is it more related to Design approach?
Making the base class a friend gives the base class access to the private members of the derived class. It is hard to tell what the reason for this is here without seeing the definition of class Base. The comment seems to indicate that the base class has member functions to create objects of the derived classes.
Generally, this is bad design. It is a bad thing when the base class knows about its derived classes at all, and it is even worse when it has access to the derived classes' private members. The dependencies should only go one way: derived classes depend on the base class, not the other way around. In other words, a change in the derived class should not break the base class.
If you need a factory, the right way to do this is to put the creation logic into a separate factory class, not into the base class.

Instantiating Derived class which inherits privately or protectedly from Base

I have the following hypothetical code:
class Base {
public:
virtual void print() {
std::cout << "Base\n";
}
// assume virtual destructor
};
class Derived : private Base {
public:
void print() {
std::cout << "Derived\n";
}
};
int main() {
// Derived d{}; works fine
Base *pd = new Derived{}; // doesn't work
pd->print();
// assume memory is deallocated
}
At first, I thought that it would work, because constructors aren't inherited anyways. But the compiler gives the error:
error: 'Base' is an inaccessible base of 'Derived'
And I'm not able to figure out what is really happening?
It's a good guess, but the problem isn't with constructors or member functions.
In the line
Base *pd = new Derived{}; // doesn't work
The compiler is implicitly converting the right side, new Derived{}, which is of type Derived*, to the type Base*.
The term that the standard uses to describe when one can implicitly convert a pointer to a derived class to a pointer to a base class is accessibility. From subsection 11.2/5:
If a base class is accessible, one can implicitly convert a pointer to a derived class to a pointer to that base class
There are a few technical conditions listed (11.2/4 if you really care) that can make a base class accessible, but Base meets none of these.
The short version is, private inheritance hides the base class and the access specifier private needs to be public for your code to compile. Hope that helps.
You are deriving Base privately, and that's why you are getting error.
With private inheritance, all members from the base class are inherited as private. This means private members stay private, and protected and public members become private. Thats why you are not able to use print()in main Compiler is not able to cast derived pointer to base type, because the inheritance is private.
In a context where the knowledge of the internals of the derived class is hidden (IE non-friend, not in a class derived from Derived) it seems like there is no relationship between the two classes.
When you try to assign to a pointer of the base type you are saying convert this Derived pointer to a Base pointer. As the inheritance is hidden, it is like you are trying to assign it to a pointer of an unrelated type. However the compiler does know that it is related, so rather than just giving you a unhelpful error, it tells you that the conversion that you are trying to do is inaccessible.

overriding super class member

I am trying to inherit a class defined in a public library while overriding some of its functions and member types and I have a few questions:
None of the functions are declared as virtual in the super class so is it still ok to override these functions?
Can I override member variables by simply declaring a variable with the same name but a different type. Is this the same as hiding?
Also, if 2 is possible, then can I do the following:
public class A {
public:
class Member {
Member (//some params) {};
}
}
class B : public A {
public:
class Member : public A::Member {
Member () :
A::Member(//some params)
{
// Some additions to B::Member
}
}
}
Note: Since I cannot change the superclass templating is out of the question.
If you hide the base class's functions - you can't override them as they're not virtual - you have to keep in mind that certain scenarios like calling via pointer or reference to the base class will not work as expected and might yield "interesting" results. You'll also run into issues if the destructor is non-virtual and you're trying to destroy the derived object via a pointer to base class.
You'd be hiding the base class's member of the same name, but again it is very likely that it will not do what you expect. The base class implementation will still reference the base class's member, while the derived class's implementation will reference the derived class's member.
No.
You might want to look into wrapping the "base" class instead of trying to derive from it.
you override virtual functions. if it is not, you are hiding.
it is name hiding.
no you can not.
No, you can't override them. It will be simply hiding them.
It's not overriding, it is hiding.
You can't.

private inheritance

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.