C++複製構造函數和賦值符的區別

有一道題目如下描述:

class t1;

class t2 = t1;

我先看見有一個等號,以爲就是賦值符來做的,其實並不是這樣的。做一個實驗好了:

[cpp] view plain copy
  1. class CTest  
  2. {  
  3. public:  
  4.  CTest();  //構造函數  
  5.  CTest(const CTest &); //複製構造函數  
  6.  CTest & operator = (const CTest &); //賦值符  
  7. };  
  8.   
  9. CTest::CTest()  
  10. {  
  11.  cout<<"Constructor of CTest"<<endl;  
  12. }  
  13.   
  14. CTest::CTest(const CTest & arg)  
  15. {  
  16.  cout<<"Copy Constructor of CTest"<<endl;  
  17. }  
  18.   
  19. CTest & CTest::operator = (const CTest & arg)  
  20. {  
  21.  cout<<"Assign function of CTest"<<endl;  
  22. }  
  23.   
  24. int main()  
  25. {  
  26.  CTest a;  
  27.  CTest b(a);  
  28.  CTest c = a; //注意,這裏仍然是使用複製構造函數  
  29.  a = c;       //使用賦值符,這裏雖然返回的引用但改變不了原值
  30.  return 0;  
  31. }  

運行的結果如下:

Constructor of CTest
Copy Constructor of CTest
Copy Constructor of CTest
Assign function of CTest

一切都是很顯然的了。

http://hi.baidu.com/calrincalrin/blog/item/b313045023fd66998d543041.html總結如下:

複製構造函數與賦值操作符之間的區別
複製構造函數又稱拷貝構造函數,它與賦值操作符間的區別體現在以下幾個方面
1.從概念上區分:
複製構造函數是構造函數,而賦值操作符屬於操作符重載範疇,它通常是類的成員函數
2.從原型上來區分:
複製構造函數原型ClassType(const ClassType &);無返回值
賦值操作符原型ClassType& operator=(const ClassType &);返回值爲ClassType的引用,便於連續賦值操作
3.從使用的場合來區分:
複製構造函數用於產生對象,它用於以下幾個地方:函數參數爲類的值類型時、函數返回值爲類類型時以及初始化語句,例如(示例了初始化語句,函數參數與函數返回值爲類的值類型時較簡單,這裏沒給出示例)
ClassType a;         //
ClassType b(a);     //調用複製構造函數
ClassType c = a;    //調用複製構造函數
賦值操作符要求‘=’的左右對象均已存在,它的作用就是把‘=’右邊的對象的值賦給左邊的對象
ClassType e;
Class Type f;
f = e;              //調用賦值操作符
4.當類中含有指針成員時,兩者的意義有很大區別
複製構造函數需爲指針變量分配內存空間,並將實參的值拷貝到其中;而賦值操作符它實現的功能僅僅是將‘=’號右邊的值拷貝至左值,在左邊對象內存不足時,先釋放然後再申請。當然賦值操作符必須檢測是否是自身賦值,若是則直接返回當前對象的引用而不進行賦值操作

以上部分博客原地址http://blog.csdn.net/randyjiawenjie/article/details/6666937

下面寫幾個自己做的引用返回的實驗

1.返回局部變量的引用

int &fun(int tmp)//
{
	return tmp;
}
int main()
{
    int a=10;
	int &b=fun(a);//
	b=5;
	printf("%d\n",a);
	printf("%d\n",b);
}
結果

10
18759016
因爲這裏的tmp並不是引用傳進來的,他只是主函數中a的一個拷貝值,而且作用域僅限fun函數,所以出了fun函數,返回的局部變量就是未定義行爲。

2.創建非引用變量接收引用返回

int &fun(int &tmp)//
{
	return tmp;
}
int main()
{
    int a=10;
	int b=fun(a);//
	b=5;
	printf("%d\n",a);
	printf("%d\n",b);
}
結果

10
5
這裏我的理解是,int b已經把變量棧分配好了,就算穿回來的是個引用,存的也只是個拷貝值

3.創建引用變量接收引用返回

int &fun(int &tmp)//
{
	return tmp;
}
int main()
{
    int a=10;
	int &b=fun(a);//
	b=5;
	printf("%d\n",a);
	printf("%d\n",b);
}
結果

5
5

發現這樣b還是相當於a的另一個名字,可以改變原值




發佈了88 篇原創文章 · 獲贊 28 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章