c++ 如果基类没有成员,那么派生类的大小是多少?

hkmswyz6  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(108)

考虑以下继承:

  1. class Base {
  2. protected:
  3. Base() { }
  4. public:
  5. double Multiply(double x);
  6. };
  7. class Derived : public Base {
  8. double _value;
  9. public:
  10. Derived(double init) : _value(init) { }
  11. double Multiply(double x) { return x*_value; }
  12. };

字符串
这段代码将用于模板化的代码库。多态性不是一个选项,因为它添加了VTable指针,从而使内存消耗加倍。
然而,我怀疑由于C要求对象的大小至少为1字节,Derived的大小将变为9字节,因此,由于填充/对齐,它将进一步变为16字节。
那么在C
中有没有一种方法可以保持Derived的大小等于double的大小(通常是8个字节)?标准对Derived的大小有什么规定?特别是,MSVC++在这种情况下是如何表现的?

5m1hhzi4

5m1hhzi41#

这被称为 * 空基优化 *,它在标准中定义如下:
1.8 C对象模型[Intro.object]
7除非它是位字段(9.2.4),大多数派生对象应该有一个非零的大小,并且应该占用一个或多个字节的存储空间。基类子对象可以有零大小。一个普通可复制或标准布局类型(3.9)的对象应该占用连续的字节存储空间。
8除非一个对象是位域或零大小的基类子对象,否则该对象的地址就是它所占用的第一个字节的地址。两个对象a和b具有重叠的生存期,但不是位域,如果其中一个嵌套在另一个中,或者如果至少有一个是零大小的基类子对象,并且它们是不同的类型,那么它们可能具有相同的地址;否则,它们具有不同的地址。
在你的例子中,继承Base类并不影响Derived类的大小。但是MSVC
只对第一个空基类执行这样的优化,所以从另外的空基类继承将导致Derived类大小的增长。我相信这已经是对MSVC++很长一段时间的批评点,因为许多其他编译器没有这个问题。如果你有很多小的辅助类,这真的很麻烦。作为一种解决方法,可以使用派生模板基类将多继承转换为单继承链:

  1. class Base1
  2. {};
  3. template< typename TBase > class Base2: public TBase
  4. {};
  5. template< typename TBase > class Base3: public TBase
  6. {};
  7. class Derived: public Base3< Base2< Base1 > >
  8. {};

字符串
MS Connect bug page.看起来他们根本不打算修复它。

展开查看全部

相关问题