C++子类继承父类私有成员变量后的大小
大佬们 我想问一下 ,c++中 子类继承了父类,那么继承了父类的私有成员变量会占子类的空间吗比如 以下的图片 我就挺纳闷的,Base1 和Base2 他们都是两个虚函数加一个私有成员变量,那也就是Base1大小是4+4+4 =12 Base2大小也应该是 4+4+4=12Derive继承了Base1 Base2 那derive的大小因该是 Base1 加上Base2 再加上Derive自己本身有的 私有成员4个字节 那应该是28呀大佬请指教 刚学c++ 在某些情况下,编译器可能会进行内存对齐,以便访问内存更加高效。这可能导致对象的大小比直接计算所有成员变量大小之和得到的结果要大。 sizeof base1按理不是 12 计算一个类对象的大小时的规律:1、空类、单一继承的空类、多重继承的空类所占空间大小为:1(字节,下同);
2、一个类中,虚函数本身、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间的;
3、因此一个对象的大小≥所有非静态成员大小的总和;
4、当类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针vPtr指向虚函数表VTable;
5、虚承继的情况:由于涉及到虚函数表和虚基表,会同时增加一个(多重虚继承下对应多个)vfPtr指针指向虚函数表vfTable和一个vbPtr指针指向虚基表vbTable,这两者总共所占的空间大小为:8(或8乘以多继承时父类的个数);理解为虚函数表和虚基表分别占4字节。即基类的虚函数表总共占4个字节,子类的虚基表每个基类地址占4个字节
6、在考虑以上内容所占空间的大小时,还要注意编译器下的“补齐”padding的影响,即编译器会插入多余的字节补齐;
7、类对象的大小=各非静态数据成员(包括父类的非静态数据成员但都不包括所有的成员函数)的总和+ vfptr指针(多继承下可能不止一个)+vbptr指针(多继承下可能不止一个)+编译器额外增加的字节。
mykofzone 发表于 2024-6-11 13:43
sizeof base1按理不是 12
是的,32位下Base1只有虚表指针占4字节,加上int字段一共是8字节。
所以问题应该是多重继承下虚表和指针是怎么在类中分布的。 xfmjn 发表于 2024-6-11 13:40
在某些情况下,编译器可能会进行内存对齐,以便访问内存更加高效。这可能导致对象的大小比直接计算所有成员 ...
我想应该是一个类中 无论多少个虚函数 都是能算4或者8字节 因为这些虚函数都被放在代码区 而这些虚函数的地址都被放在一个虚表当中 有一个指针指向数组起始地址 是这样的吧?先前没明白现在想通了 我之前以为 都是放在栈区 DEATHTOUCH 发表于 2024-6-11 14:12
是的,32位下Base1只有虚表指针占4字节,加上int字段一共是8字节。
所以问题应该是多重继承下虚表和指 ...
我想应该是一个类中 无论多少个虚函数 都是能算4或者8字节也就是一个指针的大小(不包含成员变量), 因为这些虚函数都被放在代码区 而这些虚函数的地址都被放在一个虚表当中 有一个指针指向数组起始地址。先前没想明白,查了资料看了原理,感觉自己犯了低级的错误哈哈 wddo 发表于 2024-6-11 13:55
计算一个类对象的大小时的规律:
1、空类、单一继承的空类、多重继承的空类所占空间大小为:1(字节,下同 ...
感谢解答,现在想明白了 先回答楼主的问题:c++ 中子类继承了父类,那么继承了父类的私有成员变量会占子类的空间吗?
答:会占用。因为**private 关键字是在语法层面上的限制:让子类无法访问继承过来的成员,但是在内存布局上,它就是直接把父类的成员都拿了过来**,所以在计算子类对象的大小时,也会包含继承过来的所有成员。
---
楼主后面的疑惑则涉及到:内存对齐和虚函数、虚函数表、虚表指针、以及它们在继承时的内存分布等等,真要说起来内容很多,如果楼主想要了解具体的底层逻辑,国内的书中我推荐 《C++ 新经典:对象模型》。
*下面就是从该书中截取的图片,正好描绘了楼主给出的例子中、子类 `Derive` 的内存模型:*
- 书中的例子相比较楼主给出的例子,是父类之中少了一些数据成员,但是只要记住 “**子类会把父类的数据成员直接拿过来**” 这一个规则,楼主也能自己分析了。
不过,考虑到楼主刚学习 C++,可以不用太操心一些内存布局方面的内容,因为涉及到的方面太多,就像这个例子中看似简单的 “内存大小” 已经涉及到 “对象模型”,这都需要专门一本书来讲解! FitContent 发表于 2024-6-12 00:24
先回答楼主的问题:c++ 中子类继承了父类,那么继承了父类的私有成员变量会占子类的空间吗?
答:会 ...
好的好的 ,太感谢解答了
页:
[1]