赋值运算符作为复制构造函数

时间:2018-01-24 09:30:42

标签: c++

赋值运算符可用于将一个对象的值复制到另一个对象 而不是使用复制构造函数,那么为什么我们需要一个复制构造函数?

class example  
{
    int data;
public:
    example()
    {
    }

    example(int x)
    {
        data = x;
    }
};

int main()
{
    example a(50);
    example a(b);
    //same can be done with the assignment operator
    //b = a;
    return 0;
}

2 个答案:

答案 0 :(得分:6)

因为在调用复制构造函数时,正在复制的对象尚不存在。

赋值运算符将另一个对象的值分配给存在的对象。

成员初始化等设备可以与复制构造函数一起使用,但在分配时不可用。此外,可以使用复制构造函数创建const对象。

此外,赋值运算符通常会返回对self的引用。

因此,复制构造函数和赋值运算符可能将使变异对象保持相同状态,但必然必须是这种情况。

答案 1 :(得分:1)

正如Bathsheba已经说过:副本构造函数会创建对象,赋值运算符会将值分配给已经现有< / strong>对象。一个人需要构建一个新对象,另一个需要处理在将一个对象的值分配给另一个对象时发生的任何事情。举个例子:

class Foo
{
  public:
    Foo(int x) { someValue = x; };
    int getValue() const { return someValue; };
  private:
    int someValue;
}

class Bar
{
  public:
    Bar(int y)
    {
        myFoo = new Foo(y);
        myValue = y + 1;
        myInitDone = true;
    };

    Bar(const Bar& other)
    {
        //myFoo was not yet initalized, so no need to clean it up
        myFoo = new Foo(other.myFoo->getValue()); 
        myValue = other.myValue;
        myInitDone = true;
    }

    Bar& operator=(const Bar& other)
    {
        delete myFoo; // If we don't clean up myFoo here we leak memory
        myFoo = new Foo(other.myFoo->getValue());
        myValue = other.myValue;
        // myInitDone is only set during construction due to [reason]
    }

  private:
    Foo* myFoo;
    int myValue;
    bool myInitDone;
}

复制构造函数需要设置myInitDone(仅在构造期间完成,因为 [在此插入原因] ),而分配运算符需要清理myFoo或者它会泄漏内存。