zoukankan      html  css  js  c++  java
  • 记录: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::$vftable@:
    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 ?$is_error_code_enum@PBD	size(1):
    1>  	+---
    1>  	| +--- (base class ?$integral_constant@_N$0A@)
    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::$vftable@B@:
    1>  	| &B_meta
    1>  	|  0
    1>   0	| &B::print_b 
    1>  
    1>  B::$vbtable@:
    1>   0	| -4
    1>   1	| 8 (Bd(B+4)A)
    1>  
    1>  B::$vftable@A@:
    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::$vftable@C@:
    1>  	| &C_meta
    1>  	|  0
    1>   0	| &C::print_c 
    1>  
    1>  C::$vbtable@:
    1>   0	| -4
    1>   1	| 8 (Cd(C+4)A)
    1>  
    1>  C::$vftable@A@:
    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::$vftable@B@:
    1>  	| &D_meta
    1>  	|  0
    1>   0	| &B::print_b 
    1>   1	| &D::print_d 
    1>  
    1>  D::$vftable@C@:
    1>  	| -12
    1>   0	| &C::print_c 
    1>  
    1>  D::$vbtable@B@:
    1>   0	| -4
    1>   1	| 24 (Dd(B+4)A)
    1>  
    1>  D::$vbtable@C@:
    1>   0	| -4
    1>   1	| 12 (Dd(C+4)A)
    1>  
    1>  D::$vftable@A@:
    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
    

    运行结果

  • 相关阅读:
    jdbc之存储过程的调用和调用方法
    jdbc之Statement和Preparement
    jdbc之连接Oracle的基本步骤
    Oracle之子程序(存储过程、方法、包)
    Oracle之plsql及游标
    Oracle之多表查询
    Oracle之单表查询及常用函数
    Oracle之基础操作
    IO流之字符流
    IO流之字节流
  • 原文地址:https://www.cnblogs.com/GyForever1004/p/9782682.html
Copyright © 2011-2022 走看看