cpp inheritance some misconception - c++

here i have some code
class A{
private:
int a;
public:
void abc()
{ cout << a << endl; }
};
class B : public A
{ };
main() {
B obj;
obj.abc(); // it works but why? obj.abc is printing a which should not inherit to class B because it is private.
ok so derived class inherited a public function abc() from the base class and that function is trying to output a member variable a that is not a part of derived class because it is private in base class? So how does it do that. this code prints a... but how?

a is private to class A, but since function abc is defined in class A, abc can make use of a.
B can make use of abc because abc is public and B derives from A (publicly).
a would not be available to functions defined in B.

Related

Is this the right approach to count the number of base class objects created when there is a partial virtual inheritance involved?

From what I have learnt about virtual inheritance, whenever we have a class A (the base class), classes B, C, D (all these three virtually inherit class A) then if there is a class derived which inherits from B, C and D classes is instantiated then only a single object of class A would be created.
I tried to reason about the virtual inheritance by taking different cases:
Case 1:
Assume the derived class inherits only from class B and C. Even then only a single object of class A gets instantiated, right?
I tried to verify this using this code and it certainly seems to be the case:
#include <iostream>
using namespace std;
class A
{
public:
int a;
};
class B: virtual public A
{
public:
int b;
};
class C: virtual public A
{
public:
int c;
};
class D: virtual public A
{
public:
int d;
};
class derived: public B, public C
{
public:
int y;
};
int main()
{
derived dObj;
cout<<&(dObj.B::a)<<'\n';
cout<<&(dObj.C::a)<<'\n';
return 0;
}
Output:
0x7ffc8adac1c0
0x7ffc8adac1c0
Case 2:
Assume the derived class inherits from class B, C and D, but class D doesn't inherit class A virtually. In this case, 2 objects of class A get instantiated, right? - One for B, C and one for D.
I tried to verify this using this code and it certainly seems to be the case:
#include <iostream>
using namespace std;
class A
{
public:
int a;
};
class B: virtual public A
{
public:
int b;
};
class C: virtual public A
{
public:
int c;
};
class D: public A
{
public:
int d;
};
class derived: public B, public C, public D
{
public:
int y;
};
int main()
{
derived dObj;
cout<<&(dObj.B::a)<<'\n';
cout<<&(dObj.C::a)<<'\n';
cout<<&(dObj.D::a)<<'\n';
return 0;
}
Output:
0x7ffd512429c8
0x7ffd512429c8
0x7ffd512429bc
Now here is my question:
Are my observations correct? That is, instead of just 3 classes - B, C, D, let's assume we have n classes that inherit class A, if out of them, m (1<=m<=n) classes are inherited by another class named derived, and if out of those m classes only k (0<=k<=m) classes inherit class A virtually then the number of objects of class A that get instantiated when instantiating the derived class would be = 1+m-k (if k!=0) and m (when k=0), right?
From the content written in the cppreference website it is indeed the case:
See the first example under the virtual base classes section.

Injecting an implementation into a class in C++

Consider the following example:
class A{
public: virtual void hello() = 0;
};
class B: public A{};
class C {
public: void hello(){
cout<<"Hi";
}
};
class D: public B, public C{};
The idea is that I would like to inject the implementation of hello into D through C. This doesn't seem to work unless I make C inherit from A too. Since that leads to diamond inheritance, I end up using virtual inheritance.
Is there any alternative to forcing an implementation into a derived class, without disturbing the abstract classes A and B here?
EDIT: I want a solution where I don't need to explicitly write code within D. This is because, I have many classes like D having the same implementation, which is exactly why I would like to push that implementation up to some class from which all of them inherit.
You can rewrite C as a template class that inherits from it's template argument and then derive D from C.
template <class Base>
class C : public Base {
public: void hello(){
cout<<"Hi";
}
};
class D: public C<B> {};
You can consider static inheritance/ policy classes when you need to inject an outside method into a class hierarchy. Note that injecting the method usually means that the method does not have the same name as an existing virtual in the class hierarchy (if it does, you are forced to use virtual inheritance or explicitly call with the scope :: or insert it in the class hierarchy). I called the method externalHello here.
The other options work fine as well but they conceptually point more to the fact that the injected method is not really an abstract method that could be used outside of this class hierarchy but should have been part of it in the first place.
class A
{
public:
virtual void hello() = 0;
};
class B: public A
{
public:
void hello()
{
cout<<"Hi from B" << endl;
};
};
template<typename T> class C1
{
public:
void injectedMethodUnrelatedToClassHierarchy()
{
cout<<"Hi from C1 with unrelated method" << endl;
};
void externalHello()
{
static_cast<T*>(this)->hello(); // will still call hello in B
injectedMethodUnrelatedToClassHierarchy(); // this will call hello here
};
};
class D: public B, public C1<D>{};
With client code:
D dx;
dx.hello();
dx.externalHello();
dx.injectedMethodUnrelatedToClassHierarchy();
It may work
#include<iostream>
using namespace std;
class A
{
public:
virtual void hello() = 0;
};
class C {
public: void hello(){
cout<<"Hi\n";
}
};
template<typename T>
class B: public A, public T
{
public:
void hello() override{ //override A::hello()
//do other staff
T::hello(); // call C::hello()
}
};
class D: public B<C>{
};
int main()
{
D d;
d.hello();
return 0;
}

Virtual function inheritance

I have a confusion about the inheriting the virtual property of a method.
Let's suppose we have 4 classes: class A, class B, class C and class D.
The classes are inherited by this way: A -> B -> C -> D, where A is the base class.
By this time, I'm sure about this: Beginning the class method declaration with virtual in a base class (class A), makes the method virtual for all classes derived from the base class, including the derived ones of the derived classes. (B and C class methods determined to be virtual).
The confusion is here. What if, in the base class A, there wouldn't be any virtual member. Instead, let's say, that class B declares a method to be virtual. I assume, that this change would make the function virtual for all the derived classes that belong to the inheriting chain (C and D classes). So logically, B for C and D, is a sort of their "base class", right? Or am I wrong?
You're correct.
I think that in this case the best solution is to try:
#include <iostream>
using namespace std;
class A {
public:
void print(){ cout << "print A" << endl; };
};
class B: public A {
public:
virtual void print(){ cout << "print B" << endl; };
};
class C: public B {
public:
void print(){ cout << "print C" << endl; };
};
int main()
{
A *a = new C();
B *b = new C();
a->print(); // will print 'print A'
b->print(); // will print 'print C'
return 1;
}
You are entirely correct. Child inherits what its ancestors have. Base classes can't inherit what the child has (such as a new function or variable). Virtual functions are simply functions that can be overridden by the child class if the that child class changes the implementation of the virtual function so that the base virtual function isn't called.
A is the base class for B,C,D. B is a the base class for C, D. and C is the base class for D too.
Of course you can do it. Virtual method is optional to override so it doesn't matter that you declare it in class A or B. If you dont want to use that method in class A then simply declare in in class B.

Inherited member function accessing data members

Consider the sample code below:
#include <iostream>
using namespace std;
class A
{
private:
static int a;
int b;
protected:
public:
A() : b(0) {}
void modify()
{
a++;
b++;
}
void display()
{
cout << a <<"\n";
cout << b <<"\n";
}
};
int A::a=0;
class B : public A {
private:
int b;
public:
B(): b(5)
{
}
};
int main()
{
A ob1;
B ob2;
ob1.display();
ob2.display();
return 0;
}
In the code above, the class A has a private data member band class B also has a private data member b. The function display() is used to display the data members.
When i invoke display() using ob1.display(), display() accesses the private data member b of class A. I understand that. But when i invoke display using ob2.display, which b does display() access? Is it the b of class A or b of class B? Kindly explain the why it accesses class A's b or class B's b
It will access A::b. The display method implementation in class A has no clue about the existence of B::b at all, let alone using it. For all intents and purposes, B::b is separate from A::b. Only in the scope of B itself, the name conflict makes b refer to B::b, hiding A::b. Member variables cannot be virtual.
ob2.display() will access the derived class member.
The member function call is always evaluated on this, this->display() the this in case points to object of your Base class and hence any reference to b inside the display() function is evaluated as this->b which is b of the Base class.
This is because display() of the Base class has no knowledge of whether any other class derives from it. Base class is always independent of the Derived class. To solve a problem the uual pattern followed is to provide a display() method in the Derived class which then in turn calls the dsiplay() method of the Base class.
void B::display()
{
//cout << a <<"\n";
cout << b <<"\n";
A::display();
}
It is class A. A::display() cannot access B private members.

how can a derived class function call a function of the base class?

Derived class function cannot access even the public members of the base class when the access specifier is private. But how is it that the function 'xyz' of my derived class able to call 'showofb'?
I even tried it by calling the function 'showofb' in the constructor of C. In both cases it works.
How is it able to call the function 'showofb' ?
class B
{
public:
B()
{
cout<<":B:"<<endl;
}
void showofb()
{
cout<<"show of b"<<endl;
}
};
class C : private B
{
public:
C()
{
cout<<":C:"<<endl;
}
void xyz()
{
showofb();
}
};
int main()
{
C c1;
c1.xyz();
}
Private inheritance inherits the public members of the parent as the private members of the child. A class can call its own or inherited private members.
Consider this:
class B
{
public:
B()
{
cout<<":B:"<<endl;
}
void showofb()
{
cout<<"show of b"<<endl;
}
};
class C : private B
{
public:
C() {}
};
class D : public B
{
public:
D(){};
}
int main()
{
C c1;
c1.showofb(); // WONT WORK
D d1;
d1.showofb(); // WILL WORK
}
B::showofb() is a public function. So it can be called by C. If you modify B to make showofb private, C will no longer be able to call it.
The private inheritance means that all public and protected members of B are inherited as private by C. So C can still call public and protected members of B, but any classes derived from C will not be able to call members of B.
user1001204, you appear to have a mistaken concept of private inheritance. That class C inherits from class B via private inheritance means that the inheritance relationship is hidden to anything that uses class C. Private inheritance does not hide the inheritance relationship inside Class C itself.