C++ 拷贝构造函数和重载赋值操作符不能相互调用

来源:互联网 发布:mac 显示隐藏的文件夹 编辑:程序博客网 时间:2024/06/05 10:48

拷贝构造函数调用重载赋值操作符,重载赋值操作符调用拷贝构造函数的写法都是没有意义的。

首先:

拷贝构造函数的存在意义--------是通过已有的对象构造新的对象,构造完毕后才有两个对象

重载赋值操作符的意义-----------将一个对象的值赋给另一个对象,两个对象都已经构造完毕了

拷贝构造函数----调用-----重载赋值操作符:把已有对象的值赋给一个构造中的对象,虽然这个对象的内存已经分配好了

                                                                 但是有可能导致循环调用重载赋值操作符和拷贝构造函数

重载赋值操作符---调用------拷贝构造函数:把已有对象复制并赋值给这个对象。

                                                                  导致循环调用重载赋值操作符。

总之--复制构造函数调用赋值操作符就好像正在构造的对象却用已经构造好的对象;
           赋值操作符调用复制构造函数就好像用正在构造的对象进行赋值;

例子:

例子1:拷贝构造函数调用重载赋值操作符(导致循环调用重载赋值操作符和拷贝构造函数 )

[cpp] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. class Base {  
  5. public:  
  6.     Base() {cout << "Constructor invoked!" << endl;}  
  7.     ~Base() {cout << "Destructor invoked!" << endl;}  
  8.     Base(const Base& rhs) {  
  9.         cout << "Copy constructor invoked!" << endl;  
  10.         operator=(rhs); // *this = rhs;  
  11.     }  
  12.     Base operator=(const Base& rhs) { // 问题出在这里,返回值不是引用会调用拷贝构造函数  
  13.         cout << "Copy assignment operator invoked!" << endl;  
  14.         return *this;  
  15.     }  
  16. };  
  17.   
  18. int main(int argc, char** argv) {  
  19.     cout << "Hello World C++!" << endl;  
  20.     Base a;  
  21.     Base b(a); // Base b = Base(a);  
  22.     return 0;  
  23. }  
修改后

[cpp] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. class Base {  
  5. public:  
  6.     Base() {cout << "Constructor invoked!" << endl;}  
  7.     ~Base() {cout << "Destructor invoked!" << endl;}  
  8.     Base(const Base& rhs) {  
  9.         cout << "Copy constructor invoked!" << endl;  
  10.         operator=(rhs); // *this = rhs;  
  11.     }  
  12.     Base& operator=(const Base& rhs) { // 返回引用,可以接受  
  13.         cout << "Copy assignment operator invoked!" << endl;  
  14.         return *this;  
  15.     }  
  16. };  
  17.   
  18. int main(int argc, char** argv) {  
  19.     cout << "Hello World C++!" << endl;  
  20.     Base a;  
  21.     Base b(a); // Base b = Base(a);  
  22.     return 0;  
  23. }  

这样做没有任何问题,但是破坏了拷贝构造函数的意义(不同人,可能理解不同),所以不推荐。

例子2:重载赋值操作符调用拷贝构造函数(导致循环调用重载赋值操作符 )

[cpp] view plaincopy
  1. #include <iostream>  
  2. using namespace std;  
  3.   
  4. class Base {  
  5. public:  
  6.     Base() {cout << "Constructor invoked!" << endl;}  
  7.     ~Base() {cout << "Destructor invoked!" << endl;}  
  8.     Base(const Base& rhs) {  
  9.         cout << "Copy constructor invoked!" << endl;  
  10.     }  
  11.     Base& operator=(const Base& rhs) {  
  12.         cout << "Copy assignment operator invoked!" << endl;  
  13.         *this = Base(rhs);  
  14.         return *this;  
  15.     }  
  16. };  
  17.   
  18. int main(int argc, char** argv) {  
  19.     cout << "Hello World C++!" << endl;  
  20.     Base a;  
  21.     Base b(a); // Base b = Base(a);  
  22.     b = a;  
  23.     return 0;  
  24. }  
用法例子:

  1. class   A;    
  2.  A  a;  
  3.  A  b=a;   //拷贝构造函数调用  
  4.  //或  
  5.  A  b(a);   //拷贝构造函数调用  
  6.  
  7.  A  a;  
  8.  A  b;  
  9.  b =a;   //赋值运算符调用  

你只需要记住,在C++语言里如下两种形式---均调用拷贝 构造函数

  1.  String   s2(s1);  
  2.  String   s3   =   s1;
1
2
3
4
5
6
7
8
9
10
11
12
13
class String
{
public:
String();                                //默认构造函数;
String(const String& rhs);               //复制构造函数;
String& operater=(const String& rhs);    //赋值操作符;
...
private:
char *data;
};
String s1;                              //调用默认构造函数;
String s2(s1);                          //调用复制构造函数;
String s3=s1;                           //调用复制构造函数



0 0