Multi-inheritance can be seen as an extension of single inheritance. The so-called multi-inheritance is that the relationship between the class has multiple base classes, and the relationship between derived class and each base class can still be regarded as a single inheritance.
The definition format of the mid-inheritance is as follows:
Class
{
}
Among them,
Class A
{
...
}
Class B
{
...
}
Class C: Public A, Public, B
{
...
}
Among them, the derived class C has two base classes (class A and class B), so Class C is inherited. According to the inheritance, the members of the derived class C include members of the base class B and the members of the class itself.
Multi-inherited constructor
In the case of multiple inheritance, the derived structure function format is as follows:
{
}
Where each parameter in
Multi-inheritance of the construction function is similar to that of the single inheritance, it must be responsible for the call of all base class constructors of the faction of the faction. At the same time, the number of parameters of derived class must contain the number of parameters required to complete all base classes.
The derived class constructor execution order is to perform the constructor of the opukens, and then execute the derived class itself, the execution order of each base class constructor in the same hierarchy depends on the base class sequence specified when the derived class is defined. , Independent of the order of the members initialization list defined in the derived class constructor. That is, the order in which the base class constructor is executed depends on the order of the base class when the derived class is defined. It can be seen that the sequence in the list of members of the derived class constructor can be arbitrarily arranged.
The configuration of the sect and its execution order will be described below by an example.
#include
Class B1
{
PUBLIC:
B1 (INT I)
{
B1 = i;
COUT << "Constructor B1." <}
Void Print () {cout INT B1; } Class B2 { PUBLIC: B2 (INT I) { B2 = I; COUT << "Constructor B2." <} Void Print () {cout INT B2; } Class B3 { PUBLIC: B3 (INT I) { B3 = i; COUT << "Constructor B3." <} Int getb3 () {RETURN B3; Private: Int b3; } Class A: Public B2, Public B1 { PUBLIC: A (INT I, INT J, INT K, INT L): B1 (I), B2 (J), BB (K) { A = L; COUT << "Constructor a." <} Void print () { B1 :: Print (); B2 :: Print (); Cout <} Private: Int a; B3 BB; } void main () { A aa (1, 2, 3, 4); Aa.print (); } The output result of the program is: Constructor B2.2 Constructor B1.1 Constructor B3.3 Constructor A.4 1 2 4, 3 In this program, the scope operator :: Used to solve the problem of scope conflicts. In the definition of the Print () function in the derived class A, use B1 :: Print; and B2 :: Print (); statements indicate which type of PRINT () function in the call is called, this usage should learn. C multiple inheritance 8/27/2001 8: 37: 55 · · · ·· PCVC Previous 1 2 Embodiment Generally speaking, access to base class members in derived class should be unique, however, due to multi-inheritance, it is possible to cause an unique situation in a member of a member in the base class, called the base class. Embiguity issues for members access. In fact, this problem has already appeared in the above example, recalling that in the upper example, there is a member function print () in the two bases B1 and B2 of the derived class A. If you access the print () function in the derived class, which base class is it? So there is an unsurface. However, in the above example, this problem is solved, and the method is limited by the scope operator :: If you do not limit, a two-meaning problem occurs. Let's take a simple example below to discuss the erriness issues. E.g: Class A { PUBLIC: Void f (); } Class B { PUBLIC: Void f (); Void g (); } Class C: Public A, PUBLIC B { PUBLIC: Void g (); Void h (); } If you define a class C object C1: C1; Visit the function f () C1.f (); It has an amphibian: Is F () in the Access Class A or the F () in class B is accessed? The solution can be used to eliminate erliness using the previously used membership name limits, for example: C1.A :: f (); or C1.b :: f (); However, the best solution is to define a member f (), f () in class C, decide to call A:: f (), or b :: f (), or two as needed Everything is, this, C1.f () will call C :: f (). Similarly, member function call f () in class C will also appear. E.g: VIOD C :: h () { f (); } There is an amphibian problem here, which should be modified to: Void C :: h () { A :: f (); } or Void C :: h () { B :: f (); } or Void C :: f () { A :: f (); B :: f (); } In addition, in the preceding example, there is a member function g () in class B, and there is also a member function G (). At this time, C1.g (); There is no difference, it refers to C :: g () instead of B :: g (). Because of these two g () functions, a member appearing in the base class B, a member of the derived class C, which specifies that the derived class will dominate the same name in the base class. Therefore, the g () dominating in class C in the superhe example, does not exist, and the name of the domain can be selected. When a derived class is derived from a plurality of base classes, and these base classes have a common base class, it may also occur when accessing the members described in the base class. E.g: Class A { PUBLIC: Int a; } Class B1: Public A { Private: INT B1; } Class B2: Public A { Private: INT B2; } Class C: Public B1, PUBLIC B2 { PUBLIC: INT f (); Private: INT C; } Known: C C1; The following two accesss have an unity: C1.a; C1.A :: A; The following two access are correct: C1.B1 :: A; C1.B2 :: A; The member function f () of class C can eliminate erliness: INT C :: f () { Retrun B1 :: A B2 :: A; } Due to the secondary reason, a class cannot directly inherit from the same class more than one, for example: Class A: Public B, PUBLIC B { ... } This is wrong.