【问题标题】:Should the copy constructor and copy assignment operator have the same statements?复制构造函数和复制赋值运算符是否应该具有相同的语句?
【发布时间】:2020-02-10 21:00:01
【问题描述】:

返回类型当然会不同,但概念是一样的:将数据从一个对象复制到另一个对象,对吧?

【问题讨论】:

  • 不同之处在于赋值运算符可以假设被赋值的对象已经初始化,并且必须正确清理它,而复制构造函数不能假设正在构造的对象已经初始化,因此不需要清理。实际上,通常最好根据另一个来实现一个,而不是在两者中复制相同的代码。例如,使用复制构造函数实现赋值运算符。
  • 不一样,但可能有帮助:stackoverflow.com/questions/17480396/…
  • 最好使用copy and swap idiom
  • @Yksisarvinen 我想说考虑复制和交换成语是个好主意。它并不总是最佳解决方案。例如,对于向量,C&S 总是会分配新的内存,如果 assigned-to 向量的容量 小于或等于 assigned-from 向量的大小。字符串也是如此。
  • @DanielLangr 你是对的。您的示例将是一个很好的答案,作为对 OP 声明这两个操作相同的反证。

标签: c++ operator-overloading copy-constructor assignment-operator


【解决方案1】:

copy constructor 用已经存在的对象初始化新对象。

copy assignment 将一个对象的值分配给另一个对象,这两个对象都已经存在。

【讨论】:

    【解决方案2】:

    没有。虽然复制赋值运算符确实将数据复制到另一个对象,但复制构造函数使用复制的数据初始化 new 对象。因此,它将使用其成员初始化器列表递归地调用其成员的复制构造函数,而复制赋值运算符将调用其他复制赋值运算符。

    struct Foo {
    
        Foo(Foo const &orig)
        : data{oring.data} { }
    
        Foo &operator = (Foo const &orig) {
            data = orig.data;
            return *this;
        }
    
    private:
        std::string data;
    };
    

    【讨论】:

    • 也许检查 &orig != this 以避免自动分配可能会更好:)
    • @Fareanor 这有点像contentious。在这种情况下,我相信std::string 的赋值运算符无需我检查就能正常工作。
    • 如果“数据”是指针,这段代码还能工作吗?在这种情况下,它看起来像这样: Foo(Foo const &orig) { data = new int; *data = *(orig.data); } Foo &operator = (Foo const &orig) { 删除数据;数据=新的整数; *data = *(orig.data) return *this;这有点像……
    • @Pelle 如果数据是指针,那么你需要做一个深拷贝;使用 shared_ptr 或以其他方式保护数据免受双重删除
    • @Pelle 原始拥有指针不应该被使用,所以你不需要明确的delete
    【解决方案3】:

    概念根本不同;复制构造函数创建一个不存在的新对象(并且不返回任何内容——甚至void),并且赋值运算符更新一个已经存在的对象。

    【讨论】:

      猜你喜欢
      • 2011-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 1970-01-01
      • 2014-05-18
      • 1970-01-01
      相关资源
      最近更新 更多