函數調用中參數和返回值的拷貝

本文通過一個簡單的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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章