C++中的賦值函數

1、賦值函數寫法分析 

Test& operator=(const Test &t)
{
    if(this != &t)
    {
        data = t.data;
    }
    return *this;
} 

void operator=(Test t)
{
    data = t.data;
}
void main()
{
    Test t1(10);
    Test t2;       
    t2 = t1; //在C++代碼背後實際等價於t2.operator=(t),然後將t1傳給形參t
}

(1)形參中的Test &t 與Test t

        如上兩種賦值語句的寫法,本身都可以運行,沒有錯誤,但是其內部差異以及優缺點很明顯,如上述代碼,t1給t2賦值過程中,等號實際是一個符號的重載,實際背後是將t1作爲參數傳遞,必將調用拷貝構造函數,這樣使得代碼效率降低,而使用引用傳遞,不會給形參t開闢一個臨時的空間,而是外面t1的別名,所以不會調用拷貝構造函數。

(2)形參中的const Test 與 Test

       爲了保護類中的數據,加上const後表明類中的數據不能被修改,不可在該函數內部對Test類的成員數據進行修改。例如t1是一個對象,裏面數據都被初始化爲0,需要用這個對象給其他同類對象進行賦值,我們希望其他類中數據的初始值也爲0,則直接賦值即可,但有人不小心在賦值重載函數中對Test類的數據成員進行了修改,則使用t2 = t1時,對象t2中的數據也將被修改,所以在形參前面加上const,表示我們不希望有人賦值函數中試圖修改數據,從而起到保護作用。

(3)if(this != &t)作用

       如下C++背後的代碼轉換機制中,包含一個當前對象的this指針,爲了防止自己給自己賦值,通過該判斷提高了代碼運行效率,如下代碼中,當t1給t3賦值時,屬於自己給自己賦值,因爲t3、t2本身都是t1的別名。

Test& operator(const Test &t)  轉換爲  Test& operator(Test * const this, const Test &t)

t2 = t1  轉換爲  t2.operator = (&t2,t1)

Test t1(10);
Test &t2 = t1;
Test &t3 = t2;
t3 = t1;

(4)返回類型Test 與void

      在對象的連等賦值中,因爲operator函數的參數是一個Test類型,t1是一個Test對象,而(t2.operator=(t1))也要作爲t3的operator的形參,所以t2.operator=(t1)要返回一個Test類型,return *this才能進行連等賦值。

t3=t2=t1  ->  t3.operator=(t2.operator=(t1));

(5)返回值Test的引用返回

      1.第(4)部分進行連等過程中參數的傳遞需要一個Test類型,如果類型不是引用,則需要進行初始化,此時會調用拷貝構造函數,所以一般使用引用,提高效率。

      2.並非任何代碼都提倡使用引用返回,如下代碼中tmp是我們的臨時變量,如果使用引用返回,則不在創建無名的臨時對象,此時返回引用指向真實的tmp,當該函數執行結束,tmp會被析構。我們平時的返回都會創建一個無名的臨時空間用來存放臨時變量的返回,也就是函數體作爲返回值賦值給變量或者對象。

     3.一般地,如果函數體中的返回值變量不是該函數體的臨時變量,即當函數體生命週期結束後,函數所返回的變量或者對象依然有效,此時可以使用引用返回提高效率,反正不可。

#include<iostream>
using namespace std;
 
class Test
{
public:
    Test(int d = 0);data(d)
    {
        cout <<"Create Test Object"<< endl;
    }
    Test (const Test &copy_t) 拷貝構造函數
    {
        data = copy_t.data;
    }
    Test& operator=(const Test &t)
    {
        if(this != &t)
        {
            data = t.data;
        }
        return *this;
    }
public:
    int GetData() const
    {
        return data;
    }
private:
    int data;
};
 
Test fun(Test x)
{
    int value;
    value = x.GetData();
    Test tmp(value);
    return tmp;
}

void main()
{
    Test t1(10);
    Test t2;  
    t2 = fun(t1);

}

     

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