当有复制构造函数时,是否总是需要赋值运算符?

uly*_*is2 2 c++ operator-overloading copy-constructor

我正在学习构造函数和析构函数,并且已经学会了三个规则.

我现在正在播放tutorialspoint中的一个小例子.我注意到该示例没有赋值运算符,但代码以某种方式运行良好.例如,Line a(b)当我改变a中的内容时,例如*(a.ptr),*(b.ptr)不会改变.

我还写了一个赋值运算符(注释),代码也可以.

现在我很困惑.在某些情况下,似乎只有复制构造函数就足够了.任何人都可以对此发表评论,以帮助我更好地了解调用复制构造函数所涉及的内存分配机制吗?

谢谢!

#include <iostream>

using namespace std;

class Line
{
   public:
      int getLength( void );
      Line( int len );             // simple constructor
      Line( const Line &obj);  // copy constructor
      ~Line();                     // destructor
      void doubleLength(void);
     Line &operator=(const Line &);

   private:
      int *ptr;
};

// Member functions definitions including constructor
Line::Line(int len)
{
    cout << "Normal constructor allocating ptr" << endl;
    // allocate memory for the pointer;
    ptr = new int; //simply allocates memory for one integer, and returns a pointer to it.
    *ptr = len;
}

Line::Line(const Line &obj)
{
    cout << "Copy constructor allocating ptr." << endl;
    ptr = new int;
   *ptr = *obj.ptr; // copy the value
}

//  // copy assignment operator, added by me
//  Line& Line::operator=(const Line& that)
//  {
//      if (this != &that)
//      {
//          delete ptr;
//          // This is a dangerous point in the flow of execution!
//          // We have temporarily invalidated the class invariants,
//          // and the next statement might throw an exception,
//          // leaving the object in an invalid state :(
//          this->ptr = new int;
//          this->ptr = that.ptr;

//      }
//      return *this;
//  }


Line::~Line(void)
{
    cout <<  "Freeing memory " << ptr << endl;
    delete ptr;
}
int Line::getLength( void )
{
    return *ptr;
}

void Line::doubleLength(void)
{
    *ptr = *ptr * 2;
}

void display(Line obj)
{
   cout << "Length of line : " << obj.getLength() <<endl;
}

// Main function for the program
int main( )
{
   Line line1(10);

//     Line line2 = line1; // This also calls copy constructor
   Line line2(line1);   // performed by copy assignment operator    
   line2.doubleLength();
   display(line1);
   display(line2);


   return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到输出:

Normal constructor allocating ptr
Copy constructor allocating ptr.
Copy constructor allocating ptr.
Length of line : 10
Freeing memory 0x836c028
Copy constructor allocating ptr.
Length of line : 20
Freeing memory 0x836c028
Freeing memory 0x836c018
Freeing memory 0x836c008
Run Code Online (Sandbox Code Playgroud)

jbl*_*ixr 6

Line line2 = line1; //assignment operator but copy constructor will be called implicitly
Line line3(line1); //copy constructor will be called explicitly
Run Code Online (Sandbox Code Playgroud)

从现有对象创建新对象时,将调用复制构造函数.这里line2line3新近从现有的创建line1,所以复制即使您使用构造函数被调用=.

Line line2; //default constructor is called
line2 = line1; //assignment operator is called
Run Code Online (Sandbox Code Playgroud)

这里第一行用默认构造函数声明并初始化它,第二行是赋值.所以在这里调用赋值运算符.即,当将对象分配给已初始化的对象时,将调用赋值运算符.


小智 5

赋值运算符不是必需的,但可能是可取的。

如果你有课的Foo

Foo a;     // calls normal constructor
Foo b(a);  // calls copy constructor explicitely
Foo c = b; // calls copy constructor (initialization)
b = a;     // calls assignment operator
Run Code Online (Sandbox Code Playgroud)

当对象作为函数调用(值参数)的结果被复制时,复制构造函数被调用。