See the copy of the article about virtual function inheritance and virtual inheritance interpretation better

Source: Internet
Author: User

(From: http://blog.chinaunix.net/uid-25132162-id-1564955.html) 1, empty class, empty class single inheritance, empty class multiple inheritance of sizeof
  1. #include <iostream>
  2. using namespace Std;
  3. Class Base1
  4. {
  5. };
  6. Class Base2
  7. {
  8. };
  9. Class Derived1:public Base1
  10. {
  11. };
  12. Class Derived2:public Base1, public Base2
  13. {
  14. };
  15. int main ()
  16. {
  17. BASE1 B1;
  18. Base2 B2;
  19. Derived1 D1;
  20. Derived2 D2;
  21. cout<< "sizeof (BASE1) =" <<sizeof (Base1) << "sizeof (B1) =" <<sizeof (B1) <<endl;
  22. cout<< "sizeof (BASE2) =" <<sizeof (Base2) << "sizeof (b2) =" <<sizeof (b2) <<endl;
  23. cout<< "sizeof (Derived1) =" <<sizeof (Derived1) << "sizeof (D1) =" <<sizeof (d1) <<endl;
  24. cout<< "sizeof (DERIVED2) =" <<sizeof (Derived2) << "sizeof (D1) =" <<sizeof (d1) <<endl;
  25. return 0;
  26. }
The result: sizeof (BASE1) = 1 sizeof (B1) = 1
sizeof (BASE2) = 1 sizeof (b2) = 1
sizeof (DERIVED1) = 1 sizeof (D1) = 1
sizeof (DERIVED2) = 1 sizeof (D1) = 1
You can see that all the results are 1. 2. Classes containing virtual functions and sizeof with virtual inheritance classesvirtual functions are implemented by a virtual function table (virtual table). The compiler must ensure that a pointer to a virtual function table exists in the first position in the object instance (this is to ensure that the offset of the virtual function is correctly taken).

Let's say we have a class like this:

Class Base {

Public

virtual void F () {cout << "base::f" << Endl;}

virtual void g () {cout << "base::g" << Endl;}

virtual void H () {cout << "base::h" << Endl;}

};

When we define an instance of this class, Base B, the members of its B are stored as follows:

The pointer to the virtual function table is at the front of object B.

At the end of the virtual function table, a node is added, which is the end node of the virtual function table, just like the Terminator of the string, which marks the end of the virtual function table. The value of this end flag is different under different compilers. Under Winxp+vs2003, this value is null. And in Ubuntu 7.10 + Linux 2.6.22 + GCC 4.1.3, this value is if 1, indicating there is also the next virtual function table, if the value is 0, represents the last virtual function table.

Because object B has more than one pointer to a virtual function table, and the pointer's sizeof is 4, the last sizeof containing the virtual function's class or instance is the actual data member of sizeof plus 4.

The following discusses inheritance discussions for base classes that contain virtual functions

(1) in a derived class, the virtual function of the base class is not overwritten, and the derived class also has its own virtual function, such as the following derived classes:

Class Derived:public Base

{

Public

virtual void F1 () {cout << "derived::f1" << Endl;}

virtual void G1 () {cout << "derived::g1" << Endl;}

virtual void H1 () {cout << "derived::h1" << Endl;}

};

The relationship between the base class and the derived class is as follows:

When a derived object D is defined, its members are stored as follows:

Can be found:

1) Virtual functions are placed in the table in the order in which they are declared.

2) The virtual function of the parent class precedes the virtual function of the child class.

Both the base class and the derived class sizeof are the data members of sizeof plus 4.

(2) overriding a virtual function of a base class in a derived class, assuming a derived class like this:

Class Derived:public Base

{

Public

virtual void F () {cout << "derived::f" << Endl;}

virtual void G1 () {cout << "derived::g1" << Endl;}

virtual void H1 () {cout << "derived::h1" << Endl;}

};

Relationship between base class and derived class: where the virtual function F of the base class is overridden in a derived class

When we define a derived class object D, the members of its d are stored as:

Can be found:

1) the covered F () function is placed in the location of the original parent virtual function in the virtual table.

2) functions that are not covered are still.

In this way, we can see that for the following program,

Base *b = new Derive ();

B->f ();

The position of the F () of the virtual function table in memory referred to by B has been replaced by the Derive::f () function address, and derive::f () is called when the actual call occurs. This enables polymorphism.

(3) Multiple inheritance: no virtual function overrides

Suppose the following relationship is between a base class and a derived class:

For a virtual function table in a subclass instance, the following looks like this:

We can see:

1) Each parent class has its own virtual table.

2) The member function of the subclass is placed in the table of the first parent class. (The so-called first parent class is judged in order of declaration)

Since each base class requires a pointer to its virtual function table, the sizeof of D is equal to the data member of D plus 3*4=12.

(4) Multiple inheritance, including virtual function overrides

Suppose that the base class and the derived class have the following relationship: A virtual function f that overrides a base class in a derived class

The following is a diagram of a virtual function table in a subclass instance:

As we can see, the position of F () in the three parent virtual function table is replaced by the function pointer of the subclass. This allows us to refer to the subclass as a parent of a static type and call F () of the subclass. Such as:

Derive D;

Base1 *B1 = &d;

Base2 *b2 = &d;

Base3 *b3 = &d;

B1->f (); Derive::f ()

B2->f (); Derive::f ()

B3->f (); Derive::f ()

B1->g (); Base1::g ()

B2->g (); Base2::g ()

B3->g (); Base3::g ()

3, a calculation of sizeof with virtual function and virtual inheritance

  1. #include <iostream>
  2. using namespace Std;
  3. Class Base
  4. {
  5. Public
  6. virtual void f ();
  7. virtual void g ();
  8. virtual void H ();
  9. };
  10. Class Derived1:public Base
  11. {
  12. Public
  13. virtual void F1 ();
  14. virtual void G1 ();
  15. virtual void H1 ();
  16. };
  17. Class Derived2:public Base
  18. {
  19. Public
  20. virtual void f ();
  21. virtual void G1 ();
  22. virtual void H1 ();
  23. };
  24. Class Derived3:virtual Public Base
  25. {
  26. Public
  27. virtual void F1 ();
  28. virtual void G1 ();
  29. virtual void H1 ();
  30. };
  31. Class Derived4:virtual Public Base
  32. {
  33. Public
  34. virtual void f ();
  35. virtual void G1 ();
  36. virtual void H1 ();
  37. };
  38. Class Derived5:virtual Public Base
  39. {
  40. Public
  41. virtual void f ();
  42. virtual void g ();
  43. virtual void H ();
  44. };
  45. Class Derived6:virtual Public Base
  46. {
  47. };
  48. int main ()
  49. {
  50. Cout<<sizeof (Base) <<endl; 4
  51. Cout<<sizeof (Derived1) <<endl; 4
  52. Cout<<sizeof (DERIVED2) <<endl; 4
  53. Cout<<sizeof (DERIVED3) <<endl; 12
  54. Cout<<sizeof (DERIVED4) <<endl; 12
  55. Cout<<sizeof (DERIVED5) <<endl; 8
  56. Cout<<sizeof (DERIVED6) <<endl; 8
  57. return 0;
  58. }
For base, Derived1 and DERIVED2 results are better understood based on the previous analysis of inheritance, but the way to virtual inheritance is somewhat different, according to the result of a virtual inheritance of the analysis, such as to DERIVED3 or Derived4 define an object D , there will be three with virtual functions and virtual inheritance of pointers, because it is virtual inheritance, so introduce a pointer to the virtual inheritance of the base class, the second because there is a virtual function in the base class, so the pointer needs to point to its virtual function table, because the derived class itself also has its own virtual function, because the virtual inheritance is taken, Therefore, its own virtual function will not be placed behind the virtual function table of the base class, but also to allocate a virtual function table that only stores its own virtual function, and then introduce a pointer, from the example, see DERIVED5 and Derived6 The result is 8, because in the derived class or not their own virtual function, Either all are overrides to the base class virtual function, so fewer pointers to the virtual function tables of their derived classes will result in fewer than 4. (This is a personal analysis, but the principle does not know if this is the case)

(Reference: http://www.cnblogs.com/fanzhidongyzby/archive/2013/01/14/2859064.html)

Summarize the virtual function call form, should be:

* (this pointer + adjust amount) [virtual function offset within vftable] ()

Virtual inheritance is to solve multiple copy problems of common base classes under multiple inheritance. For example, the MYCLASSC object in the upper example contains Myclassa and myclassb, but Myclassa and myclassb contain common base class MyClass. In order to eliminate the multiple existence of MyClass sub-objects, we need to make both Myclassa and MYCLASSB virtual inherit from MyClass, and then let myclassc multiple inherit from the two parent classes.

Class Myclassa:virtual Public MyClass
Class Myclassb:virtual Public MyClass
Class Myclassc:public Myclassa,public MYCLASSB

The introduction of virtual inheritance makes the model of an object very complex, except that the virtual function table pointers for each base class (Myclassa and MYCLASSB) and the common base class (MyClass) need to be recorded. Each virtual inherited MyClass parent class also needs to record a pointer vbptr of a virtual base class table Vbtable. MYCLASSC is shown in Object Model 4.

Figure 4 MYCLASSC Object model

The Virtual base class table each item records the offset of the inherited virtual base class sub-object relative to the virtual base class table pointer. For example, Myclassa's virtual base class table second item record value is 24, is the myclass::vfptr relative to the myclassa::vbptr offset, the same MYCLASSB virtual base class table second item record value 12 is also MyClass:: The offset of the vfptr relative to the myclassa::vbptr.

Unlike a virtual function table, the first item of a virtual base class table records the offset of the current sub-object relative to the virtual base class table pointer. The virtual table pointers within the Myclassa and MYCLASSB sub-objects are stored at 4-byte offsets relative to themselves, so the value is-4. Assuming that Myclassa and MYCLASSC or MYCLASSB do not define a new virtual function, that is, the virtual function table is not generated, then the value of the first field in the virtual base class table should be 0.

Through the above object organization, the compiler solves the problem of multiple copies of the public virtual base class. By using the Virtual base class table pointer of each parent class, you can find the location of the child objects of the virtual base class that are used by the public, and then access the data of the virtual base class sub-objects in turn. As for the virtual function defined by the virtual base class, it is the same as other virtual functions, in this case, if you use the virtual base class pointer myclass*pc to access the fun of the MYCLASSC object, it will be converted to the following form:

* (PC+28) [0] ()

See the copy of the article about virtual function inheritance and virtual inheritance interpretation better

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.