C + + Virtual base class Details (GO)

Source: Internet
Author: User

We know that if a derived class has more than one direct base class, and these direct base classes have a common base class, then in the final derived class, multiple copies of the same name members of the indirect common base class data member are preserved. When referencing these members with the same name, you must increase the direct base class name after the name of the derived class object to avoid generating two semantics, which uniquely identifies a member, such as:
C1. A::d isplay ()

Retaining multiple copies of the same name in a class for indirect common base classes, although sometimes necessary, can hold different data in different data members, or they can be initialized separately by constructors. But in most cases, this is a phenomenon that people do not want to appear. Because copies of multiple data members are retained, not only do they occupy more storage space, they also increase the difficulty of accessing these members and are prone to errors. And in fact, there is no need to have multiple copies.

C + + provides a method of virtual base class, so that only one member is retained when inheriting the indirect common base class. Suppose Class D is a common derived class of Class B and Class C, and Class B and Class C are also derived classes of Class A, as shown in 11.21. Class A has data members and member functions fun; derived classes B and C inherit data and fun from Class A, and Class B also adds its own data member Data_b, and Class C adds Data_c. Without a virtual base class, two copies of Class A member data are retained in Class D, expressed as int B::d ata and int C::d ata. There are also two member functions with the same name, expressed as void B::fun () and void C::fun (). The added member Data_b and Class C in class B dat_c different names and do not have to be qualified with the class name. In addition, Class D also adds its own data member Data_d and member function Fun_d.


Figure 11.21


Now, declare Class A as a virtual base class by doing the following:

  1. Class a //Declare base class A
  2. {
  3. //Code
  4. };
  5. Class B: virtual Public a //declares that Class B is a common derived class of Class A, and a is a virtual base class of B
  6. {
  7. //Code
  8. };
  9. Class C: virtual public A //Declares Class C is a common derived class of Class A, and a is the virtual base class of C
  10. {
  11. //Code
  12. };

Note: The virtual base class is not declared when the base class is declared, but when the derived class is declared, when the inheritance method is specified. Because a base class can be used as a virtual base class when a derived class is generated, and not as a virtual base class when another derived class is generated.

The general form of declaring a virtual base class is:
Class Derived classes Name: Virtual Inheritance Mode base class name
That is, when declaring a derived class, the keyword is added to the corresponding inheritance method, and after such a declaration, when the base class is inherited by a derived class through multiple derived paths, the derived class inherits the base class only once, that is, the base class member is reserved only once.

Note: To ensure that a virtual base class inherits only once in a derived class, it should be declared as a virtual base class in all direct derived classes of that base class. Otherwise, multiple inheritance of the base class will still occur.

If Class A is declared as a virtual base class in derived classes B and C, and Class A is not declared as a virtual base class in derived class D, in derived class E, although the part derived from Class B and C paths retains only one copy of the base class member, the part derived from the Class D path retains a copy of the base class member.

Initialization of virtual base class

If a constructor with parameters is defined in a virtual base class and no default constructor is defined, the virtual base class is initialized through the constructor's initialization table in all its derived classes, including derived classes that derive directly or indirectly. For example

  1. Class a //define base Class A
  2. {
  3. a(int i){ } ///base class constructor, with one parameter};
  4. Class B : Virtual public a //a as the virtual base class of B
  5. {
  6. B(int n):A(n){ } //b class constructor that initializes the virtual base class in the initialization table
  7. };
  8. Class C : Virtual public a //a as an imaginary base class for C
  9. {
  10. C(int n):A(n){ } //c class constructor that initializes the virtual base class in the initialization table
  11. };
  12. Class D : PublicB, publicC //constructor for Class D, initialization of all base classes in the initialization table
  13. {
  14. D(int n):A(n),B(n),C(n){ }
  15. };

Note: When you define a constructor for Class D, it differs from the method used previously. In the past, the constructor of a derived class simply had to be responsible for initializing its direct base class, and then its direct base class was responsible for initializing the indirect base class. Now, because the virtual base class has only one copy of the data member in the derived class, the initialization of the data member must be given directly by the derived class. If the virtual base class is not initialized directly by the last derived class, and the virtual base class is initialized by a direct derived class of the virtual base class (such as Class B and Class C), it is possible that there is a contradiction between the different initialization parameters of the virtual base class in the constructors of Class B and Class C. So the rule: in the last derived class not only is responsible for its direct base class initialization, but also responsible for the virtual base class initialization.

Some readers will ask: the constructor of Class D is called by the initialization table to the virtual base class constructor A, and the constructors of Class B and Class C also call the virtual base class constructor A through the initialization table, so that the constructor of the virtual base class is not called 3 times? You don't have to worry about it. The C + + compilation system only performs calls to the constructor of the virtual base class from the last derived class, ignoring other derived classes of the virtual base class (such as Class B and class C) calls to the virtual base class's constructor, which guarantees that the data members of the virtual base class are not initialized more than once.

Simple application example of virtual base class

[Example 11.9] in example 11. 8 (see the code for: multiple inheritance for C + + classes), add a common base class person on top of the teacher class and the student class. Some of the basic data as people are placed in person, adding some necessary data to the teacher class and the student class. The following programs can be written:

  1. #include <iostream>
  2. #include <string>
  3. Using namespace std;
  4. Declaring a public base class person
  5. Class person
  6. {
  7. Public:
  8. person(string nam,char s,int a) //constructor
  9. {
  10. Name=nam;
  11. Sex=s;
  12. Age=a;
  13. }
  14. Protected: //Protect members
  15. string name;
  16. char sex;
  17. int age;
  18. };
  19. Declares a direct derived class of person teacher
  20. Class Teacher:virtual public person //Declare person to be a virtual base class for common inheritance
  21. {
  22. Public:
  23. Teacher(string nam,char s,int a, string t):person(nam , S, a)//constructor
  24. {
  25. Title=t;
  26. }
  27. Protected: //Protect members
  28. string title; //Job title
  29. };
  30. Declares a direct derived class of person student
  31. Class Student:virtual public person //Declare person to be a virtual base class for common inheritance
  32. {
  33. Public:
  34. Student(string nam,char s,int a,float SCO) //constructor
  35. :person(Nam, S, a),score(Sco){ } //initialization table
  36. Protected: //Protect members
  37. float score; //score
  38. };
  39. A derived class that declares multiple inheritance graduate
  40. Class graduate: PublicTeacher, publicStudent //teacher and Student as direct base classes
  41. {
  42. Public:
  43. graduate (string Nam,char s,int astring T,float sco,float W//constructor
  44. :person(Nam, S, a),Teacher(Nam, S, a, T),Student(nam , S, a, SCO),wage(w){}
  45. //Initialize table
  46. void show( ) //output of postgraduate data
  47. {
  48. cout<<"Name:"<<name<<endl;
  49. cout<<"Age:"<<age<<endl;
  50. cout<<"Sex:"<<sex<<endl;
  51. cout<<"score:"<<score<<endl;
  52. cout<<"title:"<<title<<endl;
  53. cout<<"wages:"<<wage<<endl;
  54. }
  55. Private:
  56. float wage; //Wages
  57. };
  58. Main function
  59. int main( )
  60. {
  61. graduate grad1("Wang-li",' f ', ', 'Assistant ',89.5 ,1234.5);
  62. Grad1. Show( );
  63. return 0;
  64. }


A two-point description of the program:
1) Note the wording of the various constructors. A constructor with 3 parameters is defined in the person class, which initializes the data member name, sex, and age. In the constructors of the teacher and student classes, the initialization table is mandated to include initialization of the base class, although for virtual base classes, the compilation system does not call the constructor of the base class, but it should still be written in the uniform form of the derived class constructor. In the constructor of the last derived class graduate, both the call to the virtual base class constructor and the initialization of its direct base class are included.

2) in the Graduate class, only one copy of the members of the base class is retained, so you can use the show function in the Graduate class to refer to the data member of the public base class person in the Graduate class object name, sex, and age values, without the addition of the base class name and the domain operator (::), Does not produce two semantics.

As you can see: Use multiple inheritance with great care, and often there are two of semantic issues. The example described earlier is simple, and if you derive more layers, multiple inheritance is more complex, programmers are prone to mihunzhen, and programming, debugging, and maintenance will become more difficult. Therefore, many professionals believe that: do not advocate the use of multiple inheritance in the program, only if it is relatively simple and not easy to appear two of the ambiguity or is necessary to use multiple inheritance, the problem can be solved with single inheritance do not use multiple inheritance. Also for this reason, some object-oriented programming languages (such as Java,smalltalk) do not support multiple inheritance.

Article Source: http://see.xidian.edu.cn/cpp/biancheng/view/238.html

C + + Virtual base class Details (GO)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.