我可以制作C ++对象的按位副本吗?

时间:2009-10-05 22:44:24

标签: c++

可以使用按位复制复制C ++对象吗?我的意思是使用memcopy_s?是否存在可能出错的情况?

6 个答案:

答案 0 :(得分:17)

如果它们是普通旧数据(POD)类型,那么这应该有效。任何包含其他类实例的类都可能会失败,因为您在不调用其副本构造函数的情况下复制它们。它失败的最可能方式是它们的一个析构函数将释放一些内存,但是你已经重复指向它的指针,所以你试着从你复制的一个对象中使用它并获得段错误。简而言之,除非它是POD,否则不要这样做,你确定它永远是POD。

答案 1 :(得分:10)

不,这样做会导致很多问题。您应该始终使用赋值运算符或复制构造函数来复制C ++类型。

使用按位复制会破坏任何类型的资源管理,因为在一天结束时,您将剩下2个对象,其中1个构造函数已运行且将运行2个析构函数。

以ref计数指针为例。

void foo() {
  RefPointer<int> p1(new int());
  RefPointer<int> p2;
  memcpy(&p2,p1,sizeof(RefPointer<int>));
}

现在p1和p2都保持相同的数据但尚未通知内部引用计数机制。两个析构函数都会认为它们是数据的唯一所有者,可能导致值被破坏两次。

答案 2 :(得分:1)

如果它是单个对象,为什么不使用赋值运算符(我认为编译器生成的赋值运算符可以用memcpy实现,如果它是如此有利,并且编译器更好地知道你的类是否是一个POD。)

如果要复制对象数组,可以使用std :: copy。根据实现情况,这最终可能会使用memmove(还有一件事情你可以搞砸 - 缓冲区可能会重叠;我不知道非标准memcpy_s是否会以某种方式检查)涉及的类型允许。同样,决策由编译器完成,即使修改了类型,也会使其正确。

答案 3 :(得分:0)

这取决于您尝试复制的C ++对象的实现。一般来说,C ++对象内存的所有者就是对象本身,因此尝试用memcopy_s这样的“移动”或“复制”它会落后于它,这会让你经常遇到麻烦。

通常,如果要复制或移动C ++对象,则类本身中的API可以促进这一点。

答案 4 :(得分:0)

通常,如果你的结构包含指针,你就无法记忆它,因为结构最有可能分配新的内存空间并指向那些内存空间。 memcpy无法处理。

但是,如果您的类只有原始的非指针类型,那么应该能够。

答案 5 :(得分:0)

除了两个实例中资源管理调用不平衡的问题之外,你最终会在memcopy之后(如@JaredPar和@rmeador所指出的那样),如果对象支持实例ID的概念,那么做memcopy会让你失望两个具有相同ID的实例。这可能会导致各种“有趣”的问题在以后捕获,特别是如果您的对象被映射到数据库。