C++四種繼承關係中內存分佈

1、單一繼承不含虛函數

在這種情況下,對象會保持基類的原樣性,並且一個class derived class object表現出來的東西,是其自己的members加上其base classes members的總和。

class Point2d  
{  
    int a;  
    char b;  
};  

class Point3d : public Point2d  
{  
    char c;  
};

對於上述類,其模型如下:

2、單一繼承含虛函數

與單一繼承不含虛函數唯一不同的是,在含有虛函數時,vptr放置的位置。如果vptr放置在起始位置處,則會表現出非自然多態。如果在在尾處,則可以自然多態。下面是一個構造的具有虛函數的繼承類。

class Point2d
{
    int a;
    char b;
};

class Point3d : public Point2d
{
    char c;
public:
    virtual void print()
    {
        std::cout << "this is the Point2d" << std::endl;
    }
};
class Point4d : public Point3d
{
    char d;
public:
    void print() override
    {
        std::cout << "this is the Point4d" << std::endl;
    }
};

對於上述類,其模型如下:

3、多重繼承

多重繼承的問題主要發生於derived class objects和其第二或後繼的base class之間的轉換。他的內存分佈其實各個部分相加再加上自己的部分。

class Point3d
{
private:
    int _x, _y, _z;
public:
    virtual void print()
    {
        std::cout << "this is the point3d" << std::endl;
    }

};

class Vertex
{
private:
    char v;
public:
    virtual void print()
    {
        std::cout << "this is the vertex" << std::endl;
    }
};

class Vertex3d : public Point3d, public Vertex
{
    int num;
};

對於這個類,它們的模型是:

在這個模型中,類型轉換是如何發生的呢?

Point3d* ptrP3d1;
Vertex* ptrVtx1;
Vertex3d* ptrVtx3d1;
Vertex3d vtx3d1;
ptrP3d1 = &vtx3d1;//自然多態,不需要編譯器參與
ptrVtx1 = &vtx3d1;//非自然多態,需要編譯器參數 ptrVtx1 = (Vertex*)((char*)(&vtx3d1)+sizeof(Point3d));
ptrVtx3d1 = &vtx3d1;
ptrVtx1 = ptrVtx3d1;//非自然多態,需要編譯器 ptrVtx1 =ptrVtx3d1?(Vertex*)((char*)(ptrVtx3d1)+sizeof(Point3d)):0

4、虛擬繼承

Class如果內含一個或多個virtual base class subobjects,將被分割成兩部分:一個不變區域和一個共享區域。

共享區域指的是virtual base class subobject這一部分,其位置會因為每次的派生操作而有變化。

下面我將分析一組虛擬派生繼承,以及它在vs中的內存分佈。代碼如下:

class Point
{
    char p;
};

class Point2d : public virtual Point
{
    int a;
    int aa;
    char aaa;
};

class Point3d : public virtual Point2d
{
    int b;
public:
    virtual void print()
    {
        std::cout << "this is the Point3d" << std::endl;
    }
};

class Vertex : public virtual Point2d
{
    int c;

public:
    virtual void print()
    {
        std::cout << "this is the Vertex" << std::endl;
    }
};

class Vertex3d : public Point3d, public Vertex
{
    int d;
};

在這段代碼中,其所構造的模型如下: