How to call derived class method in private inheritance? - c++

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.

Related

Calling Derived class method which is private from Base class pointer [duplicate]

I have a Base class pointer pointing to derived class object. The method foo() is public in base class but private in derived class. Base class foo() is virtual. So when i call foo() from Base class pointer, Vptr Table has the address of derived class foo(), BUT its private in Derived class ...so how is it getting called.??
I understand Run time polymorphism and i also understand that the Access specifiers work for compile time and Virtual concept works at run time. So there shall be No Compiler error.
My question is : Is this is a loop hole through which we can call private methods of Derived class ? or Its expected to behave this way.
Any good Explanation for this behavior.
Thanks a lot in advance.
CODE :
class A
{
public:
virtual void foo()
{
std::cout << "In A";
}
};
class B:public A
{
private:
void foo()
{
std::cout << "In B ??? Its Private Method :-( ";
}
};
int main()
{
A* ptr = new B();
ptr->foo();
return 0;
}
It's private method, but since it's virtual - it can be called.
n3690 11.5/1
The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by
the rules for a function that later overrides it.
Why this? Since
n3690 11.5/2
Access is checked at the call point using the type of the expression used to denote the object for which the
member function is called (B* in the example above). The access of the member function in the class in
which it was defined (D in the example above) is in general not known.
Access level is a compile-time concept. The runtime doesn't know if a method was declared private or public. Those are there for your convenience.
This is actually a good coding standard - a virtual method should be ideally public in the base class and private or protected in derived classes. This will force the caller to use the interfaces rather than the actual types (of course, this isn't always practical, but a good thing to take into account).
The concrete type is abstracted away in your case, as it should be. The base method is declared public and you're calling it through a pointer to a base, so it's allowed.

Extend the existing C++ class

I'd like to add the extra functionality without changing the existing class.
Say,
class base{
public:
int i;
base(){i = 1;}
virtual void do_work(){ /*Do some work*/ }
};
If I want to add serialization member function to it, I will simply create a derived class
class derived : public base{
public:
void serialize();
};
void derived::serialize(){
cout << "derived class" << endl;
}
And I do need to handle existing base objects,e.g.
int main(){
base a;
derived & b = static_cast<derived &>(a);
b.serialize();
}
This example runs without problems. But I do know the downcast through static_cast is something to be avoided in general.
But I'd like to know if the downcast for this particular use case can be considered safe since the derived class only has one extra member function. Will it has some potential undefined behavior for accessing vtable?
The way you're extending Base you're not making use of the vtable because you have no virtual methods. It may be easier to think of it as Derived has A Base; That you created a new class that contains a Base member variable.
My Suggestion.
Template Function
I personally would go with a template function. You can keep all the work in your original question, and avoid the need of adding virtual calls to your class.
template<typename T>
void serialize_object(T& t)
{
t.serialize()
}
And then based on your example.
Derivied d;
serialize_object(d);
The big benefit is that you're not adding runtime cast here. The compiler will inform you if you pass an object that doesn't have a method serialize.
Go Virtual
If you really want to handle this through a virtual interface do so.
struct Serializable{
virtual void serialize()=0;
virtual ~Serializable(){}
}
class Derived : public Serializable {
public:
void serialize() override;
}
void Derivied::serialize()
{
std::cout << "Yah\n";
}
Then in your code.
Derivied d;
Serializable& s = dynamic_cast<Serializable&>(d);
However, the big concern here is who is the owner of your base class? Did they provide a virtual dtor? If not, then making use of std::unique_ptr or std::shared_ptr could cause you to not deal directly with the interface.
If you can write the serialize function in a derived class without touching private or protected members then you should simply make it a free function. That solves everything.
You can't just cast a base class object to an inherited class. Any members in the inherited class will not have been created and initialized. You need to start with an object of the inherited class.
You can go the other way, of course, and call base class functions from a function of a class inherited from the base, because the base class object will always be there as part of the inherited class object, by definition.
If you have a pointer to the base class, and you build with RTTI, you can use dynamic_cast to cast to an inherited class, but that cast will fail and return NULL if the object is not of the class you're trying to cast to. But usually it's better to call a virtual function than to use dynamic_cast.

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.

Derived class Private method is getting called

I have a Base class pointer pointing to derived class object. The method foo() is public in base class but private in derived class. Base class foo() is virtual. So when i call foo() from Base class pointer, Vptr Table has the address of derived class foo(), BUT its private in Derived class ...so how is it getting called.??
I understand Run time polymorphism and i also understand that the Access specifiers work for compile time and Virtual concept works at run time. So there shall be No Compiler error.
My question is : Is this is a loop hole through which we can call private methods of Derived class ? or Its expected to behave this way.
Any good Explanation for this behavior.
Thanks a lot in advance.
CODE :
class A
{
public:
virtual void foo()
{
std::cout << "In A";
}
};
class B:public A
{
private:
void foo()
{
std::cout << "In B ??? Its Private Method :-( ";
}
};
int main()
{
A* ptr = new B();
ptr->foo();
return 0;
}
It's private method, but since it's virtual - it can be called.
n3690 11.5/1
The access rules (Clause 11) for a virtual function are determined by its declaration and are not affected by
the rules for a function that later overrides it.
Why this? Since
n3690 11.5/2
Access is checked at the call point using the type of the expression used to denote the object for which the
member function is called (B* in the example above). The access of the member function in the class in
which it was defined (D in the example above) is in general not known.
Access level is a compile-time concept. The runtime doesn't know if a method was declared private or public. Those are there for your convenience.
This is actually a good coding standard - a virtual method should be ideally public in the base class and private or protected in derived classes. This will force the caller to use the interfaces rather than the actual types (of course, this isn't always practical, but a good thing to take into account).
The concrete type is abstracted away in your case, as it should be. The base method is declared public and you're calling it through a pointer to a base, so it's allowed.

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.