C++ 对象内存模型

字数 307阅读 1220

(很久之前写的了,先扔上来

继承 (无虚函数时)

  1. 单继承
  • 类的对象的内存布局如下所示:
2.png
  • 类中的成员变量的存储顺序从低地址到高地址按照成员变量的声明的顺序存储。
  • 类中的静态成员变量(由 static 关键字所修饰)单独存储在程序的 .data 段中,不与特定的对象相关联。
  • 若派生类的成员变量(或成员函数)与基类的成员变量(或成员函数)同名,则基类中的成员变量(或成员函数)被隐藏(最好不要去访问被隐藏的成员,假如一定需要访问,需用类名受限的方式来访问)。
class A {
public:
    int t;
    void f() { ; }
}

class B : public A {
public:
    int t;
    void f() { ; }
    void test
    {
        t = 0;     // 访问的是 B::t
        f();       // 访问的是 B::f()
        A::t = 1;  // 访问的是 A::t
        A::f();    // 访问的是 A::f()
    }
}

void func()
{
    B b;
    b.t = 0;        // 访问的是 B::t
    b.f();          // 访问的是 B::f()
    b.A::t = 1;     // 访问的是 A::t
    b.A::f();       // 访问的是 A::f()
}
  1. 多继承
3.png
  1. 虚继承
4.png

继承 (有虚函数时)

  1. 单继承
class A {
public:
    A():_a(0x0a0a0a0a) { }
    int _a;
    virtual void f() { }
};

class B : public A {
public:
    B():_b(0x0b0b0b0b) { }
    int _b;
    virtual void f() { }
    virtual void g() { }
};

class C : public B {
public:
    C():_c(0x0c0c0c0c) { }
    int _c;
    virtual void h() { }
};
5.png
  1. 多继承
class A {
public:
    A():_a(0x0a0a0a0a) { }
    int _a;
    virtual void f() { }
};

class B : public A {
public:
    B():_b(0x0b0b0b0b) { }
    int _b;
    virtual void g() { }
};

class C {
public:
    C():_c(0x0c0c0c0c) { }
    int _c;
    virtual void h() { }
};

class D: public C, public B {
public:
    D():_d(0xd0d0d0d0) { }
    int _d;
    virtual void g() { }
    virtual void j() { }
};
6.png
  1. 虚继承
  • 派生类中无新的虚函数,不覆盖基类的虚函数
class A {
public:
    A():_a(0x0a0a0a0a) { }
    int _a;
    virtual void f() { }
};

class B : public virtual A {
public:
    B():_b(0x0b0b0b0b) { }
    int _b;
};

如图:

7_3.png
  • 派生类中无新的虚函数,覆盖了基类的虚函数
class A {
public:
    A():_a(0x0a0a0a0a) { }
    int _a;
    virtual void f() { }
    virtual void g() { }
};

class B : public virtual A {
public:
    B():_b(0x0b0b0b0b) { }
    int _b;
    virtual void f() { }
};

如图:

7_4.png
  • 派生类有新的虚函数,不覆盖基类的虚函数
class A {
public:
    A():_a(0x0a0a0a0a) { }
    int _a;
    virtual void f() { }
};

class B : public virtual A {
public:
    B():_b(0x0b0b0b0b) { }
    int _b;
    virtual void g() { }
};

如图:

7_5.png
  • 派生类中有新的虚函数,覆盖了基类的虚函数
class A {
public:
    A():_a(0x0a0a0a0a) { }
    int _a;
    virtual void f() { }
    virtual void g() { }
};

class B : public virtual A {
public:
    B():_b(0x0b0b0b0b) { }
    int _b;
    virtual void f() { }
    virtual void h() { }
};

如图:

7_6.png

推荐阅读更多精彩内容