本文通過一個簡單的demo,說明了函數調用過程中參數和返回值的拷貝情況,如果將參數和返回值改爲其引用,則會避免本次拷貝。
#include <iostream>
using namespace std;
//函數調用中的參數與返回值的copy
class Test
{
public:
Test(int a=0):m_a(a)
{
cout << "Test()!"<<endl;
}
Test(Test& that)
{
this->m_a = that.m_a;
cout << "Test(Test& )!"<<endl;
}
Test& operator =(const Test& that)
{
m_a = that.m_a;
cout << "Test& operator =(const Test& that)!"<<endl;
return *this;
}
private:
int m_a;
};
//直接使用對象作爲函數參數和返回值的情況
void show(Test t)
{
cout << "void show(Test )" <<endl;
}
Test show1(Test t)
{
cout << "Test show1(Test )" <<endl;
return t;
}
//使用對象引用作爲函數參數和返回值的情況
void show2(Test& t)
{
cout << "void show(Test )" <<endl;
}
Test& show3(Test& t)
{
cout << "Test show1(Test )" <<endl;
return t;
}
int main()
{
int num,num1;
//賦值表達式的值是左值
(num = 5) = 7;
num1 = num = 100;
cout << "num:" << num << endl;
cout << "num1:" << num1 << endl;
//直接使用對象作爲函數參數和返回值的情況
Test t1(1);
Test t2(t1);
//如果拷貝構造函數爲Test(Test that){}
//即參數爲類對象而不是引用,則會造成無限遞歸
//Test t2(t1); ==> Test t2(Test that=t1);
//而將t1傳給拷貝構造函數做參數時,需要將t1拷貝構造給that,這裏就需要拷貝構造函數,則就調用了它本身,出現了無限遞歸。
//所以類的拷貝構造函數參數必須爲引用。
cout << "--------------------" << endl;
show(t1);//先進行了參數拷貝構造,然後調用函數
cout << "-----------------------" << endl;
show1(t1);//先進行參數拷貝構造,然後調用函數,最後將返回值拷貝到臨時變量,如果未接收,則立馬死亡
cout << "-----------------------" << endl;
t2 = show1(t1);//先進行參數拷貝構造,然後調用函數,接着將返回值拷貝到臨時變量,最後將臨時變量的值賦值給t2
cout << "-----------------------" << endl << endl;
/*輸出爲:
num:100
num:100
Test()!
Test(Test& )!
-----------------------
Test(Test& )!
void show(Test )
------------------------
Test(Test& )!
Test show1(Test )
Test(Test& )!
-------------------------
Test(Test& )!
Test show1(Test )
Test(Test& )!
Test& operator =(const Test& that)!
*/
//使用對象引用作爲函數參數和返回值的情況
cout << "----------------------" << endl;
show2(t1);//調用函數
cout << "-----------------------" << endl;
show3(t1);//調用函數,最後將返回值拷貝到臨時變量,如果未接收,則立馬死亡
cout << "-----------------------" << endl;
t2 = show3(t1);//調用函數,最後將臨時變量的值賦值給t2
/*輸出爲:
-----------------------
void show(Test )
------------------------
Test show1(Test )
-------------------------
Test show1(Test )
Test& operator =(const Test& that)!
*/
return 0;
}