首页 > 其他 > 详细

对象模型

时间:2019-05-12 15:45:17      阅读:209      评论:0      收藏:0      [点我收藏+]

对象模型:对象在内存是如何存放的

存放规则:  

  1. class内存对齐规则和struct相同。

  2. class 成员函数和成员变量分开存放,每个对象有独享的成员变量(堆栈全局数据),同一类的所有对象共享同一成员函数(代码段)。

       3. 调用成员函数时将对象地址传递给成员函数(隐式传递),成员函数通过对象地址(this指针)访问成员变量。 

  4. 对象只包含了成员变量,没有包含成员函数。

#include<iostream>
#include<string>
using namespace std;

class A
{
    int a;            // 堆栈全局段   addr  0x7ffffc6795a0
    int b;            // 堆栈全局段   addr  0x7ffffc6795a4
    char  c;         // 堆栈全局段   addr  0x7ffffc6795a8
    double d;         // 堆栈全局段   addr  0x7ffffc6795b0
public:
    void print()      // 代码段
    {
     cout << "addr of a = " << &a << endl;
     cout << "addr of b = " << &b << endl;
     cout << "addr of c = " << &c << endl;
     cout << "addr of d = " << &d << endl;
    }
};


class B
{
    int a;            
    int b;            
    char c;            
    double d;        
public:
    void print()   
    {
     cout << "addr of a = " << &a << endl;
     cout << "addr of b = " << &b << endl;
     cout << "addr of c = " << &c << endl;
     cout << "addr of d = " << &d << endl;
    }
};


int main(void)
{
    cout << "size of A = " << sizeof(A) << endl;
    A a;
    a.print();
    B* p = reinterpret_cast<B*>(&a);  // 通过地址可以直接访问修改private成员
    p->a = 1;                          // private,protect,public关键字只在编译期有效
    p->b = 2;                          // private,protect,public关键字只在运行期无效
    p->c = c;
    p->d = 3;   
    a.print();                         // 对象a的地址被传递到A类的print()函数。
    return 0;
}

 

子类对象模型:  

  1. 子类对象模型时父类成员叠加子类成员得到的。

  2. 父类成员函数在代码段,子类对象成员函数也在代码段  

#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    int a;
    int b;void print()
    {
        cout << "addr of a = " << &a << endl;  // 0x7ffff70cea14
        cout << "addr of b = " << &b << endl;  // 0x7ffff70cea18
    }
};

class Child: public Parent
{
private:
    int c;
public:
    void print()
    {
        cout << "addr of a = " << &a << endl;  // 0x7ffff70cea1c
        cout << "addr of b = " << &b << endl;  // 0x7ffff70cea20
        cout << "addr of c = " << &c << endl;  // 0x7ffff70cea24
    }
};

int main()
{
    cout << " size of Parent =  " << sizeof(Parent) <<  endl;  // 8
    cout << " size of Child =  " << sizeof(Child) <<  endl;    // 12 父类成员加子类成员
  Parent p;
  Child c;
  p.print();
  c.print();
return 0; }

 

 

 多态的对象模型:

 虚函数实现多态的原理:

  1. 编译器为类创建一个虚函数表。

  2. 对象定义一个指针指向虚函数表。

  2. 虚函数表是存储指向虚函数的指针一个数据结构。

  3. virtual 关键字定义的成员 函数会自动放入虚函数表。 

多态调用时:p->vir_func();
p    -->   vptr     -->     vtable   -->  0xff000111
函数调用 --> 虚函数表指针 --> 虚函数表中函数指针  --> 虚函数地址    

 

   

#include <iostream>
#include <string>

using namespace std;

class Parent
{
protected:
    int a;
    int b;
public:
    virtual void print()
    {
        cout << "addr of a = " << &a << endl;  //0x7fffdd1934d8
        cout << "addr of b = " << &b << endl;  // 0x7fffdd1934dc
    }
};

class Child : public Parent
{
    int c;
public:  
    void print()
    {
        cout << "there should be a address of  virtual_table " <<  endl; //
        cout << "addr of a = " << &a << endl;  //  0x7fffdd1934e8
        cout << "addr of b = " << &b << endl;  //  0x7fffdd1934ec
        cout << "addr of c = " << &c << endl;  //  0x7fffdd1934f0
    }
};

struct Test
{
    void* v_ptr;   // 虚函数表指针
    int a;
    int b;
    int c;
};

int main()
{
    Child c;
    Parent p;
    c.print();
    p.print();
    
    cout << "sizeof(Parent) = " << sizeof(Parent) << endl;        // 16 = 4+4+8        8存放的是虚函数表地址
    cout << "sizeof(Child) = " << sizeof(Child) << endl;          // 24 = 4+4+4+(4)+8  8存放的是虚函数表地址
    
    Test* test_p = reinterpret_cast<Test*>(&c);

    cout << " addr of virtual_table = " << &test_p->v_ptr << endl;   // 0x7fffc0f14390  虚函数表指针存放在对象内存的最开始
    cout << " addr of test.a =  " << &test_p->a << endl;             // 0x7fffc0f14398
    cout << " addr of test.b =  " << &test_p->b << endl;             // 0x7fffc0f1439c
    cout << " addr of test.c =  " << &test_p->c << endl;             // 0x7fffc0f143a0

    return 0;
}

 

对象模型

原文:https://www.cnblogs.com/zsy12138/p/10852395.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!