c++ - C++ 中 sizeof 的行为

标签 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。

我想我需要进行动态转换以弄清楚如何获得我在每种情况下构造为“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/

相关文章:

c++ - 将字符串元素转换为整数 (C++11)

c++ - 用户定义的类和标准类之间有区别吗?

linux - 在双 Xeon 设置的/proc/meminfo 中看不到内存

c++ - 打开共享对象时出错 : SunGrid Engine

c++ - C和C++中将int值转换为char指针的区别

c++ - 在 ostream 上使用 std::endl 使我的文件成为二进制文件

java - 作为对象容器的 Singleton 类型的类

java - 为什么 Java 不支持泛型 Throwables?

c++ - 从结构到 LPVOID 的类型转换

memory - 为什么进程的地址空间分为四个段(文本、数据、堆栈和堆)?