当前位置:编程学习 > C/C++ >>

探究C++对象模型

先引用两句名言作为开场白:

"C++老手分两类:一种人把语言用得烂熟,OO观念也有;另一种人不但如此,还对于台面下的机制,如编译器合成的default constructor、object的内存布局等有莫大的兴趣。"

"了解C++对象模型,绝对有助于你在语言本身以及面向对象观念两方面的层次提升。"

首先以Point类为例

 


再看下对象模型

 


这个模型好像跟我们以往的认知有些不一致呀,vtable首四个字节怎么是type_info的指针?type_info是RTTI的内容,是编译器用来进行类型识别的,它到底存不存在呢?

用代码测试一下


[cpp]
// VirtualTable.cpp : Defines the entry point for the console application.  
//  
 
#include "stdafx.h"  
#include <iostream>  
using namespace std; 
 
class Base { 
    private: 
        int x; 
     
     public: 
            virtual void f() { cout<<"Base::f"<<endl; }; 
            virtual void g() { cout<<"Base::g"<<endl; }; 
            virtual void h() { cout<<"Base::h"<<endl; }; 
            Base(){x = 2;}; 
 
  
}; 
 
 
 
 
class Derive : public Base{ 
    private: 
    int y; 
     public: 
            virtual void f1() { cout<<"Derive::f1"<<endl; }; 
            virtual void g1() { cout<<"Derive::g1"<<endl; }; 
            virtual void h1() { cout<<"Derive::h1"<<endl; }; 
            Derive(){y = 3;}; 
  
}; 
 
int main(int argc, char* argv[]) 

 
    typedef void(*Fun)(void); 
  
    Base b; 
    Derive d; 
  
    Fun pFun = NULL; 
  
    cout <<"虚函数表入口指针地址"<< (int*)(&b) << endl; 
    cout <<"虚函数表的地址"<< (int*)*(int*)(&b) << endl; 
 
    cout <<"Base — 第一个数据成员"<< *((int*)(&b)+1) << endl; 
    cout <<"Derive — 第一个数据成员"<< *((int*)(&d)+1) << endl; 
    cout <<"Derive — 第二个数据成员"<< *((int*)(&d)+2) << endl; 
  
    // Invoke the first virtual function   
    pFun = (Fun)*((int*)*(int*)(&b)); 
     
    pFun = (Fun)*((int*)*(int*)(&b)+0);  // Base::f()  
    pFun(); 
    pFun = (Fun)*((int*)*(int*)(&b)+1);  // Base::g()  
    pFun(); 
    pFun = (Fun)*((int*)*(int*)(&b)+2);  // Base::h()  
    pFun(); 
    //以上代码说明 虚函数表位于对象内存的最开始的位置  
    pFun = (Fun)*((int*)*(int*)(&d)+0);  // Base::f()  
    pFun(); 
    pFun = (Fun)*((int*)*(int*)(&d)+1);  // Base::g()  
    pFun(); 
    pFun = (Fun)*((int*)*(int*)(&d)+2);  // Base::h()  
    pFun(); 
    pFun = (Fun)*((int*)*(int*)(&d)+3);  // Derive::f1()  
    pFun(); 
    pFun = (Fun)*((int*)*(int*)(&d)+4);  // Derive::g1()  
    pFun(); 
    pFun = (Fun)*((int*)*(int*)(&d)+5);  // Derive::h1()  
    pFun(); 
 
 
    system("pause"); 
    return 0; 

// VirtualTable.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
using namespace std;

class Base {
 private:
  int x;
 
     public:
            virtual void f() { cout<<"Base::f"<<endl; };
            virtual void g() { cout<<"Base::g"<<endl; };
            virtual void h() { cout<<"Base::h"<<endl; };
   Base(){x = 2;};

 
};

 


class Derive : public Base{
 private:
 int y;
     public:
            virtual void f1() { cout<<"Derive::f1"<<endl; };
            virtual void g1() { cout<<"Derive::g1"<<endl; };
            virtual void h1() { cout<<"Derive::h1"<<endl; };
   Derive(){y = 3;};
 
};

int main(int argc, char* argv[])
{

 typedef void(*Fun)(void);
 
    Base b;
 Derive d;
 
    Fun pFun = NULL;
 
    cout <<"虚函数表入口指针地址"<< (int*)(&b) << endl;
    cout <<"虚函数表的地址"<< (int*)*(int*)(&b) << endl;

 cout <<"Base — 第一个数据成员"<< *((int*)(&b)+1) << endl;
 cout <<"Derive — 第一个数据成员"<< *((int*)(&d)+1) << endl;
 cout <<"Derive — 第二个数据成员"<< *((int*)(&d)+2) << endl;
 
    // Invoke the first virtual function
    pFun = (Fun)*((int*)*(int*)(&b));
   
 pFun = (Fun)*((int*)*(int*)(&b)+0);  // Base::f()
 pFun();
    pFun = (Fun)*((int*)*(int*)(&b)+1);  // Base::g()
 pFun();
    pFun = (Fun)*((int*)*(int*)(&b)+2);  // Base::h()
 pFun();
 //以上代码说明 虚函数表位于对象内存的最开始的位置
 pFun = (Fun)*((int*)*(int*)(&d)+0);  // Base::f()
 pFun();
    pFun = (Fun)*((int*)*(int*)(&d)+1);  // Base::g()
 pFun();
    pFun = (Fun)*((i

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,