关于重载拷贝构造函数和赋值运算符

 

  在C++中,下面三种对象需要调用拷贝构造函数:

 

  1) 一个对象以值传递的方式传入函数体;

 

  2) 一个对象以值传递的方式从函数返回;

 

  3) 一个对象需要通过另外一个对象进行初始化;

 

       如果在前两种情况不使用拷贝构造函数的时候,就会导致一个指针指向已经被删除的内存空间。对于第三种情况来说,初始化和赋值的不同含义是构造函数调用的原因。事实上,拷贝构造函数是由普通构造函数和赋值操作符共同实现的。 

       例如:

       int b = 6;

       int a = b;    // 拷贝构造函数

 

       int a;          // 构造函数

       a = b;         // 赋值操作符  

       什么时候需要重载拷贝构造函数和赋值操作符?

       当用一个对象给另一个对象初始化,或将一个对象的值赋给另一个对象时,如果该对象的成员中含指针的时候,需要重载拷贝构造函数或赋值运算符。

       例如,有一个类A:

 

 

       class A 

      {

       public:

       A()

      {

         n = 0;

         p = new int;

      }

       ~A()

      {

         delete p;

      }

      private:

      int n;

      int *p;

      };

      当使用语句“A a; A b = a;”为b初始化时,将调用默认拷贝构造函数,相当于执行操作“b.n = a.n; b.p = a.p”,这将导致b.p指向的地址发生改变(指向了为a.p分配的内存)。在系统析构a、b时,便会发生有一块内存被释放两次,而另一块内存无法得到释放的问题。

       解决方法就是重载A的拷贝构造函数:

       A(A & a)

      {

         n = a.n;

         p = new int;

         *p = *(a.p);

      }

       这样只是把让b.p和a.p的值相等,而指向的地址不同,在析构的时候便不会出问题。

      (注意:重载拷贝构造函数,必须先显式定义构造函数,否则,编译器会将拷贝构造函数误认为是构造函数,于是对象构造时调的是拷贝构造函数,而非系统默认的构造函数)

        重载赋值运算符的情况与重载拷贝构造函数类似,只不过一个是发生在类对象的初始化,一个发生在对象的赋值。

 

 

你可能感兴趣的:(关于重载拷贝构造函数和赋值运算符)