using virtual inheritance to solve the diamond problem
how many instances of Base class are instantiated for one instance of secDerived which is derived from Derived class when you instantiate a secDerived demolist11_7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
using namespace std;
class Animal
{
public:
Animal()
{
cout << "animal constructor" << endl;
}
int age;
};
class Bird : public Animal
{
public:
Bird()
{
cout << "Bird constructor" << endl;
}
};
class Mammal : public Animal
{
public:
Mammal()
{
cout << "Mammal constructor" << endl;
}
};
class Reptile : public Animal
{
public:
Reptile()
{
cout << "reptile constructor" << endl;
}
};
class Platypus : public Mammal, public Bird, public Reptile
{
public:
Platypus()
{
cout << "platypus constructor" << endl;
}
};
int main()
{
Platypus duckBilled;
// duckBilled.age=10
return 0;
}
output
1 | animal constructor |
As the output demonstrates, you have three instances of Animal created automatically for every single instance of a Platypus. This is ridiculous is still one animal. If uncommenting line 53, you get a compilation error simply because the compiler doesn't know whether you want to set Mammal::Animal::age or Bird::Animal::age or Reptile::Animal::age. It even more ridiculous, you could set all three:
1 | duckBilled.Mammal::Animal::age = 10; |
Obviously, one duckBilled should have only one age. We can solve this problem by using the keyword virtual
1 | class Derived2: public virtual Base |
improved code using virtual for demolist11_7
e.g. Demonstrating how virtual keyword in inheritance hierarchy helps restrict the number of instances of Base class to one. demolist11_8
1 |
|
output
1 | animal constructor |
As the output demonstrates, the virtual keyword used in the relationship between classes Mammal Bird Reptile ensures that when these classes are grouped together under Platypus the common base Animal exits only in a single instance. Also note that line 41 the usage of keyword final to ensure that class platypus cannot be used as a base class.
the
virtualkeyword in c++ is used in different contexts for different purposes.Summary:
- a function declared
virtualmeans that an exiting overriding function in a derived class invoked- an inheritance relationship declared using keyword
virtualbetween classesDerived1andDerived2that inherits from classBasethats means that another classDerived3which inherits fromDerived1andDerived2still result in the creation of only one instance ofBaseduring the instantiation of typeDerived3.