C++ 对象内存布局 (3)

假定多层继承的各类之间的关系如下图。假定派生类不override基类的虚函数,即Base2不override Base1中声明的虚函数vfBase1(),Base3不override Base2中声明的虚函数vfBase2(),Derived不override Base3中声明的虚函数vfBase3()。

  

 

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5  
 6 
 7 class Base1
 8 
 9 {
10 
11 public:
12 
13          int m_base1;
14 
15         
16 
17          inline virtual void vfBase1_1()
18 
19          {
20 
21                    cout << "This is in Base1::vfBase1_1()" << endl;
22 
23          }
24 
25 };
26 
27  
28 
29 class Base2 : public Base1
30 
31 {
32 
33 public:
34 
35          int m_base2;
36 
37  
38 
39          inline virtual void vfBase2_1()
40 
41          {
42 
43                    cout << "This is in Base2::vfBase2_1()" << endl;
44 
45          }
46 
47 };
48 
49  
50 
51 class Base3 : public Base2
52 
53 {
54 
55 public:
56 
57          int m_Base3;
58 
59  
60 
61          inline virtual void vfBase3_1()
62 
63          {
64 
65                    cout << "This is in Base3::vfBase3_1()" << endl;
66 
67          }
68 
69 };
70 
71  
72 
73 class Derived : public Base3
74 
75 {
76 
77 public:
78 
79          int m_derived;
80 
81  
82 
83          inline virtual void fd()
84 
85          {
86 
87                    cout << "This is in Derived::fd()" << endl;
88 
89          }
90 
91 };
92 
93  

Derived对象的memory layout图解如下:

 

 

 

对象内存布局 (9)基础上做些修改:派生类override基类的虚函数,即Base2 override Base1中声明的虚函数vfBase1(),Base3 override Base1中声明的虚函数vfBase1()和Base2中声明的虚函数vfBase2(), Derived override Base1中声明的虚函数vfBase1()、Base2中声明的虚函数vfBase2()和Base3中声明的虚函数vfBase3()。运行结果如下:

Derived对象的memory layout图解如下:


 

在C++中,一个类实例化得到的结果就是一个对象。一个类包含成员变量和成员函数,其中成员变量又分为nonstatic成员变量和static成员变量;成员函数又可以分为nonstatic成员函数、static成员函数以及virtual成员函数。一个对象包含可能存在的vfptr以及它声明的或基类继承而来的nonstatic成员变量,static成员变量、static成员函数、nonstatic成员函数以及virtual函数均存在于对象之外。

 

VC2005中有一个非常重要的编译选项:

对于查看类的对象的内存布局,微软内部在VC2005中(要先进入Microsoft Visual Studio -> Visual Studio Tools -> Visual Studio 2005命令提示)提供了一个非常重要的编译选项:/d1reportSingleClassLayout

   比如,如果向查看文件Polymorphism06.cpp中的类Child的对象在内存中的分布情况,先进入cmd命令窗口,改变目录到Polymorphism06.cpp所在的目录,然后键入如下命令:

         cl Polymorphism06.cpp /d1reportSingleClassLayoutChild

回车得到如下结果:

 

 

(注意:除上面关于内存布局的信息外还有很多其他信息)

 

有时我们会发现输出中会出现vtordisp,它到底是是什么意思呢,请看下面MSDN的解释:

The vtordisp pragma is applicable only to code that uses virtual bases. If a derived class overrides a virtual function that it inherits from a virtual base class, and if a constructor or destructor for the derived class calls that function using a pointer to the virtual base class, the compiler may introduce additional hidden "vtordisp" fields into classes with virtual bases.

 

The vtordisp pragma affects the layout of classes that follow it. The /vd0 and /vd1 options specify the same behavior for complete modules. Specifying off suppresses the hidden vtordisp members. Specifying on, the default, enables them where they are necessary. Turn off vtordisp only if there is no possibility that the class's constructors and destructors call virtual functions on the object pointed to by the this pointer.

 

vtordisp is now deprecated and will be removed in a future release of Visual C++.

 

/vd编译器选项会影响全局编译模式。使用vtordisp编译指示可以在基于类方式上打开或禁止vtordisp域:

#pragma vtordisp(off)

class GetReal:virtual public{...};

#pragma vtordisp(on)

 

这是一个过时的东西,以后的VC编译器也不会在支持了。

 


 

posted @ 2013-10-27 22:05  0弓虽  阅读(194)  评论(0编辑  收藏  举报