c ++中sizeof的行为

时间:2018-02-26 06:23:57

标签: c++ oop memory memcpy

当我用c ++做sizeof时,我一定会得到"整个对象"?我问,因为我要使用memcpy将对象复制到其他内存区域(从一开始可能是一个愚蠢的想法,对吧?)。

我担心的是,我可能无法获得整个对象,但只有属于该类的部分现在才能获得。它是否有意义或者我是否感到困惑?

编辑示例

 class A{ public:  int a = 123; };
 class B: public A{ public: int b = 321; };
 class C : public B{ public: int c = 333; };

 C c_ = C();
 B b_ = C();
 A a_ = C();

std::cout << sizeof(a_) << " , " << sizeof(b_) << " , " << sizeof(c_) << std::endl;

似乎给了我4,8,12。

我想我需要进行动态投射以弄清楚如何获得&#34;整体&#34;我构建为&#34; C&#34;在每种情况下分类?

1 个答案:

答案 0 :(得分:5)

sizeof将始终返回对象的静态大小。请注意,在您的示例中,它将与真实对象大小一致,因为没有多态性;当你做的时候

A a = B();

a 类型为A - 您刚刚使用新的A对象初始化新的B对象,从而导致切片(a初始化时使用与B()相同的A字段进行初始化。

更好的例子是:

B b;
A *a = &b;

在这种情况下,*a确实属于动态类型B,但sizeof(*a)仍会返回sizeof(A),而不是sizeof(B)

有几种方法可以获得对象的动态大小:

  • 在施工时将其保存到现场;
  • 理论上,您可以定义一个执行return sizeof(*this);的虚拟方法,并在所有派生类中重新定义它。

话虽如此,最后一种方法不会特别有用,因为做多平面类等非平凡类型的memcpy是未定义的行为(所以即使是第一种方法,也就是我想象的那样)你想用多态类型来做这件事。)

复制多态类问题的常见方法是接受这样一个事实:它们必须存在于堆中,并定义clone()方法virtual A * clone() {return new B(*this);}B是每个派生类中的派生类,并在需要副本时调用clone()

请注意,你可以采取更微妙的技巧;一旦我有一个类层次结构,它有一个虚拟方法为每个派生类调度一个位置new,一个用于析构函数,但你真的必须知道你在做什么(在我的情况下,我是在调用它们union包含每个派生类的实例,因此大小和对齐不是问题)。