记录:C++类内存分布(虚继承与虚函数)

工具:VS2013

先说一下VS环境下查看类内存分布的方法:


先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如果写上/d1 reportSingleClassLayoutXXX(XXX为类名),则只会打出指定类XXX的内存布局。

编译后,输出如图的内存布局:

测试代码

#include <iostream>

using namespace std;

typedef void(*FUN)();

class A{
public:
    int a;

    virtual void print(){}
    virtual void print_a(){
        cout << "print_a()" << endl;
    }
}; 

class B : virtual public A{
public:
    int b;
    void print(){}
    virtual void print_b(){
        cout << "print_b()" << endl;
    }
};

class C : virtual public A{
public:
    int c;

    void print(){}
    virtual void print_c(){
        cout << "print_c()" << endl;
    }
};

class D : public B, public C{
public:
    int d;

    void print(){}
    virtual void print_d(){
        cout << "print_d()" << endl;
    }
};

int main()
{
    D derived;

    FUN *pFun = (FUN*)((*(int*)(A*)(&derived) + 4));

    (*pFun)();

    system("Pause");

    return 0;
}

对象内存分布

1>  class A size(8):
1>      +---
1>   0  | {vfptr}
1>   4  | a
1>      +---
1>
1>  A::[email protected]:
1>      | &A_meta
1>      |  0
1>   0  | &A::print
1>   1  | &A::print_a
1>
1>  A::print this adjustor: 0
1>  A::print_a this adjustor: 0
1>
1>
1>  class [email protected]  size(1):
1>      +---
1>      | +--- (base class [email protected][email protected])
1>      | +---
1>      +---
1>
1>
1>
1>  class B size(20):
1>      +---
1>   0  | {vfptr}
1>   4  | {vbptr}
1>   8  | b
1>      +---
1>      +--- (virtual base A)
1>  12  | {vfptr}
1>  16  | a
1>      +---
1>
1>  B::[email protected]@:
1>      | &B_meta
1>      |  0
1>   0  | &B::print_b
1>
1>  B::[email protected]:
1>   0  | -4
1>   1  | 8 (Bd(B+4)A)
1>
1>  B::[email protected]@:
1>      | -12
1>   0  | &B::print
1>   1  | &A::print_a
1>
1>  B::print this adjustor: 12
1>  B::print_b this adjustor: 0
1>
1>  vbi:       class  offset o.vbptr  o.vbte fVtorDisp
1>                 A      12       4       4 0
1>
1>
1>  class C size(20):
1>      +---
1>   0  | {vfptr}
1>   4  | {vbptr}
1>   8  | c
1>      +---
1>      +--- (virtual base A)
1>  12  | {vfptr}
1>  16  | a
1>      +---
1>
1>  C::[email protected]@:
1>      | &C_meta
1>      |  0
1>   0  | &C::print_c
1>
1>  C::[email protected]:
1>   0  | -4
1>   1  | 8 (Cd(C+4)A)
1>
1>  C::[email protected]@:
1>      | -12
1>   0  | &C::print
1>   1  | &A::print_a
1>
1>  C::print this adjustor: 12
1>  C::print_c this adjustor: 0
1>
1>  vbi:       class  offset o.vbptr  o.vbte fVtorDisp
1>                 A      12       4       4 0
1>
1>
1>  class D size(36):
1>      +---
1>      | +--- (base class B)
1>   0  | | {vfptr}
1>   4  | | {vbptr}
1>   8  | | b
1>      | +---
1>      | +--- (base class C)
1>  12  | | {vfptr}
1>  16  | | {vbptr}
1>  20  | | c
1>      | +---
1>  24  | d
1>      +---
1>      +--- (virtual base A)
1>  28  | {vfptr}
1>  32  | a
1>      +---
1>
1>  D::[email protected]@:
1>      | &D_meta
1>      |  0
1>   0  | &B::print_b
1>   1  | &D::print_d
1>
1>  D::[email protected]@:
1>      | -12
1>   0  | &C::print_c
1>
1>  D::[email protected]@:
1>   0  | -4
1>   1  | 24 (Dd(B+4)A)
1>
1>  D::[email protected]@:
1>   0  | -4
1>   1  | 12 (Dd(C+4)A)
1>
1>  D::[email protected]@:
1>      | -28
1>   0  | &D::print
1>   1  | &A::print_a
1>
1>  D::print this adjustor: 28
1>  D::print_d this adjustor: 0
1>
1>  vbi:       class  offset o.vbptr  o.vbte fVtorDisp
1>                 A      28       4       4 0

运行结果

原文地址:https://www.cnblogs.com/GyForever1004/p/9782682.html

时间: 2024-08-25 10:01:31

记录:C++类内存分布(虚继承与虚函数)的相关文章

C++ Primer学习笔记32_面向对象编程(3)--继承(三):多重继承、虚继承与虚基类

C++ Primer学习笔记32_面向对象编程(3)--继承(三):多重继承.虚继承与虚基类 一.多重继承 在C++语言中,一个派生类可以从一个基类派生,称为单继承:也可以从多个基类派生,称为多继承. 多重继承--一个派生类可以有多个基类 class <派生类名> : <继承方式1> <基类名1>,<继承方式2> <基类名2>,... { <派生类新定义成员> }; 可见,多继承与单继承的区别从定义格式上看,主要是多继承的基类多于一个

C++ 虚继承和虚函数同时存在的对象模型

如果说没有虚函数的虚继承只是一个噩梦的话,那么这里就是真正的炼狱.这个C++中最复杂的继承层次在VC上的实现其实我没有完全理解,摸爬滚打了一番也算得出了微软的实现方法吧,至于一些刁钻的实现方式我也想不到什么理由来解释它,也只算是知其然不知其所以然吧. 分2个阶段来探讨: 1.      有虚函数的派生类虚继承了没有虚函数的基类: 2.      有虚函数的派生类虚继承了有虚函数的基类: 1.  基类无虚函数 1.1 虚.实基类都没有虚函数 这种情况也还算比较简单.因为虚函数表指针一定是会放在最开

[转]C++类内存分布

转自:http://www.cnblogs.com/jerry19880126/p/3616999.html 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 工欲善其事,必先利其器,我们先用好Visual Studio工具,像下面这样一步一步来: 先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如果写上/d1

C++类内存分布

转载:http://www.cnblogs.com/jerry19880126/p/3616999.html 书上类继承相关章节到这里就结束了,这里不妨说下C++内存分布结构,我们来看看编译器是怎么处理类成员内存分布的,特别是在继承.虚函数存在的情况下. 工欲善其事,必先利其器,我们先用好Visual Studio工具,像下面这样一步一步来: 先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如果写上/d1

c++类内存分布解析

首先使用Visual Studio工具查看类的内存分布,如下: 先选择左侧的C/C++->命令行,然后在其他选项这里写上/d1 reportAllClassLayout,它可以看到所有相关类的内存布局,如果写上/d1 reportSingleClassLayoutXXX(XXX为类名),则只会打出指定类XXX的内存布局.近期的VS版本都支持这样配置. 下面可以定义一个类,像下面这样: 1 class Base 2 { 3 int a; 4 int b; 5 public: 6 void Comm

C++虚继承和虚基类

看如下代码: 1 #include <iostream> 2 3 using namespace std; 4 5 class A { 6 public: 7 A() {}; 8 9 protected: 10 int m_a; 11 }; 12 13 class B : public A 14 { 15 public: 16 B(){}; 17 18 protected: 19 int m_b; 20 }; 21 22 class C : public A 23 { 24 public: 2

虚继承和虚函数继承

虚继承主要用于菱形 形式的继承形式 虚继承是为了在多继承的时候避免引发歧义, 比如类A有个就是a,B继承了A,C也继承了A,当D多继承B,C时,就会有歧义产生了,所以要使用虚拟继承避免重复拷贝. 虚函数继承是解决多态性的,当用基类指针指向派生类对象的时候,基类指针调用虚函数的时候会自动调用派生类的虚函数,这就是多态性,也叫动态编联 虚函数继承: class A { virtual void fun() {cout < <'A' < <endl;}; }; class B : pub

虚继承与虚函数继承

虚继承主要用于菱形 形式的继承形式. 虚继承是为了在多继承的时候避免引发歧义,比如类A有个就是a,B继承了A,C也继承了A,当D多继承B,C时,就会有歧义产生了,所以要使用虚拟继承避免重复拷贝.虚函数继承是解决多态性的,当用基类指针指向派生类对象的时候,基类指针调用虚函数的时候会自动调用派生类的虚函数,这就是多态性,也叫动态编联 虚函数继承:class A{    virtual void fun() {cout < <'A' < <endl;};};class B : publi

C++多重继承中的虚继承和虚函数举例

上一篇虚继承举例:http://10638473.blog.51cto.com/10628473/1964414 本文将A类中的show()函数前加上virtual关键字. //多重继承 #include <iostream> using namespace std; class A { public:     int a;     A(int a=0):a(a)     {         cout<<"A基类A::A()"<<endl;