代码之家  ›  专栏  ›  技术社区  ›  Mehran ShankarSangoli

我能做一个C++对象的按位复制吗?

c++
  •  5
  • Mehran ShankarSangoli  · 技术社区  · 15 年前

    C++对象可以使用位拷贝复制吗?我的意思是使用memcopy\s?是否存在这样一种可能出错的情况?

    6 回复  |  直到 15 年前
        1
  •  17
  •   rmeador    15 年前

    如果它们是纯旧数据(POD)类型,那么这应该可以工作。任何包含其他类实例的类都可能失败,因为您在复制它们时没有调用它们的复制构造函数。它最有可能失败的方式是,它们的一个析构函数将释放一些内存,但您复制了指向它的指针,因此您尝试从复制的对象中使用它并获得一个segfault。简而言之,除非它是一个豆荚,而且你确信它永远是一个豆荚,否则不要这样做。

        2
  •  10
  •   JaredPar    15 年前

    不,这样做会导致很多问题。您应该总是使用赋值操作符或复制构造函数复制C++类型。

    作为一个例子来考虑一个REF计数指针。

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

    现在p1和p2都保存着相同的数据,但尚未通知内部ref计数机制。两个析构函数运行时都认为它们是数据的唯一所有者,这可能导致值被析构函数两次。

        3
  •  1
  •   UncleBens    15 年前

    memcpy 如果这是非常有利的,并且编译器更清楚地知道您的类是否是POD。)

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

        4
  •  0
  •   fbrereto    15 年前

    通常,如果C++对象被复制或移动,则在类本身中有API来促进这一点。

        5
  •  0
  •   Blindy    15 年前

    但是,如果您的类只有基本的、非指针类型,那么 能够

        6
  •  0
  •   Franci Penov    15 年前

    除了在memcopy之后的两个实例中存在不平衡的资源管理调用问题(正如@JaredPar和@rmeador所指出的),如果对象支持实例ID的概念,那么执行memcopy将给您留下两个具有相同ID的实例。这可能会导致以后要查找的各种“有趣”问题,尤其是当对象映射到数据库时。