在 C++ 中,放置新和复制构造函数实现复制赋值运算符,这是一个好的做法吗?

In C++, placement new and copy constructor implementing copy assignment operator, is it a good practice?

提问人:Theo Mars 提问时间:12/28/2021 更新时间:12/28/2021 访问量:210

问:

给定代码

struct Foo{
  Foo(const Foo &other){
    i = other.i;
  };

  Foo &operator=(const Foo &other){
    if(this == &other){
      return (*this);
    }

    new (this) Foo(other);
    return (*this);
  };
  
  int i = 0;
};


struct Bar{
  Bar &operator=(const Bar &other){
    if(this == &other){
      return (*this);
    }

    this->i = other.i;
    return (*this);
  };

  Bar(const Bar &other){
    (*this) = other;
  };
  
  int i = 0;
}

假设类中的所有内容都是可复制的,那么避免上述两种形式(类 Foo 和 Bar)中的一些重复代码(考虑具有大量成员的类)是否是一种好的做法,是否有任何潜在的危险? 如果是这样,哪一个更好?

C++ 构造函数 Placement-New 复制分配

评论

2赞 Peter 12/28/2021
两者都是不好的做法。这两种方法的一个后果是,复制或分配任何派生自 或 无法正常工作的类(或者,充其量,很难正常工作)。FooBar
1赞 Daniel Langr 12/28/2021
使用放置新有什么特别的原因吗?避免这种代码重复的标准解决方案是复制和交换惯用语。例如,在这个现场演示中,为两个选项生成的机器代码完全相同:godbolt.org/z/8bn7zbhM4。那么为什么要放置新的呢?
1赞 fabian 12/28/2021
一般来说不是一个好主意;将成员类型从更改为,就造成了内存泄漏。 是可复制的...intstd::stringstd::string
1赞 Richard Critten 12/28/2021
在执行 placement new 之前,需要手动调用析构函数,以正确销毁任何成员变量和基类。例如,如果类包含成员变量,则放置 new 将覆盖泄漏它曾经拥有的内存。std::stringstd::string
2赞 Artyer 12/28/2021
如果复制构造函数可能会抛出放置 new,则会遇到问题。和“考虑具有大量成员的类”:使用默认的复制赋值运算符/复制构造函数。如果你在复制时需要做某些事情,你的类也不应该有很多成员(将其分解为多个类并组成,应用最小责任原则)

答: 暂无答案