当我在 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。
我想我需要进行动态转换以弄清楚如何获得我在每种情况下构造为“C”类的“完整”对象?
最佳答案
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
是未定义的行为(因此即使是第一个方法也是如此,因为我想您会希望对多态类型执行此操作)。
复制多态类问题的常见方法是接受它们必须存在于堆中的事实,并定义执行 virtual A * clone 的
(其中 clone()
方法() {return new B(*this);}B
是派生类)在每个派生类中,并调用 clone()
每当你需要一份拷贝。
请注意,您可以使用一些更微妙的技巧;一旦我有一个类层次结构,它有一个虚拟方法分派(dispatch)到每个派生类的放置 new
和一个用于析构函数,但你真的必须知道你在做什么(在我的例子中我正在调用它们通过 union
包含每个派生类的实例,因此大小和对齐不是问题)。
关于c++ - C++ 中 sizeof 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48982572/