// 何時調用拷貝構造函數,何時會調用賦值操作?
//
記得Effective C++中有個條款是關於何時調用拷貝構造函數和賦值運算符的,覺得這個知識點挺有意思的,可能也是很多新手包括我自己比較疑惑的地方,所以就研究了一下,下面是分兩種情況分別說明了何時調用拷貝構造函數和賦值運算符,當然調用拷貝構造函數的時機很多,這裏僅僅列出了一種情況,這一種是比較容易跟賦值運算相混淆的,也就是下面的第3種情況。能想到的就這三種,有知道其它情況的童鞋希望告知,感激不盡。
以下情況都會調用拷貝構造函數:
1. 一個對象以值傳遞的方式傳入函數體
2. 一個對象以值傳遞的方式從函數返回
3. 一個對象需要通過另外一個對象進行初始化。
代碼段一:調用拷貝構造函數的一種情況
#include "stdafx.h"
#include<iostream>
using namespace std;
class A
{
public:
A(int a):i_data(a)
{
cout<<"constructor of A"<<endl;
}
A(const A& t)
{
cout<<"copy constructor"<<endl;
this->i_data = t.i_data;
}
void print() const
{
cout<<"i_data is:"<<(this->i_data)<<endl;
}
private:
int i_data;
};
int _tmain(int argc, _TCHAR* argv[])
{
A a(5);
A aa = a;
aa.print();
system("pause");
return 0;
}
程序的運行結果:
很明顯這種情況調用了拷貝構造函數,因爲A aa=a這個是用a來初始化aa,也就是aa在實例化的時候必然要調用構造函數,而且這個時候用另一個對象a來初始化aa,所以要調用拷貝構造函數。
調用賦值運算符的情況:
#include "stdafx.h"
#include<iostream>
using namespace std;
class A
{
public:
A(int a):i_data(a)
{
cout<<"constructor of A"<<endl;
}
A(const A& t)
{
cout<<"copy constructor"<<endl;
this->i_data = t.i_data;
}
void print() const
{
cout<<"i_data is:"<<(this->i_data)<<endl;
}
private:
int i_data;
};
int _tmain(int argc, _TCHAR* argv[])
{
A a(5);
A aa(10);
aa = a;
aa.print();
system("pause");
return 0;
}
程序運行的結果:
程序只在主函數中作了很小的改動,但是程序的運行方式發生了顯著的變化。很明顯這裏沒有調用拷貝構造函數,僅僅調用了構造函數和賦值運算符,aa=a執行的時候,aa這個對象已經構造出來了,此時只是將a賦值給aa,跟第一種情況用a來初始化aa有明顯的不同。
總結:
在有對象生成的時候並用另一個同類對象初始化這個要生成的對象的時候調用拷貝構造函數,而在對象已經生成的情況下,則調用賦值運算符