C++-C++子类对象的内存结构问题?

C++-C++子类对象的内存结构问题?

归属感 发布于 2016-11-02 字数 315 浏览 1026 回复 3
class Based
{
public:
Based(int n):num(n){}
private:
int num;
};

class Dervied : public Based
{
public:
Dervied(int n, int m):Based(n), mem(m){}
private:
double mem;
};

int main()
{
Dervied d(2, 3);
return 0;
}

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

虐人心 2017-07-01 3 楼

便于子类向基类转换时的内存截断,因为每个子类的大小是不确定的,如果把子类的部分放在前面,那么将子类转换成基类的时候直接按基类的大小进行内存截断就会出问题,要实现正确的截断的话就要用到别的机制了,比较复杂,所以把基类部分放在前面的话,可以直接按基类的大小进行截断,得到正确的结果!

夜无邪 2017-03-07 2 楼

这样设计很方便,当派生类的指针转成基类的指针时,不需要计算偏移量。直接使用就行了。
Derived *d = new Derived;
Based *b = d;
b和d的值是一样的。如果把基类的数据成员放在后面,那就要计算偏移量了。一上面的例子为例的话。
b的值是d的值加上double mem,8个字节的偏移量。

参考维基百科:
非POD类的内存布局没有被C++标准规定。例如,许多流行的C++编译器通过将父类的字段和子类的字段并置来实现单继承,但是这并不被标准所需求。这种布局的选择使得将父类的指针指向子类的操作是平凡的(trivial)。一个正确书写的C++程序在任何情况下都不应该对被继承字段的布局有任何假定。
http://zh.wikipedia.org/zh-cn/C%2B%2B%E7%B1%BB

灵芸 2017-02-28 1 楼

这样做的原因是,既然派生类要保留基类的所有属性和行为,自然地,每个派生类的实例都包含了一份完整的基类实例数据。在D中,并不是说基类C的数据一定要放在D的数据之前,只不过这样放的话,能够保证D中的C对象地址,恰好是D对象地址的第一个字节。这种安排之下,有了派生类D的指针,要获得基类C的指针,就不必要计算偏移量了。几乎所有知名的C++厂商都采用这种内存安排(基类成员在前)。在单继承类层次下,每一个新的派生类都简单地把自己的成员变量添加到基类的成员变量之后。