C語言運算子的過載詳解

2022-10-08 05:06:07 字數 2924 閱讀 5747

目錄

我們先討論下面**,並複習前面的內容

class complex

complex(double r, double i) :real(r), image(i) {}

~complex() {}

//complex add(const complex* this,const complex &c)

complex add(const complex& x)const

void print() };

int main()

直接return可以使用無名函式直接代替將亡值物件,相比可以省一次物件的構建

我們再分析如果我們使用引用返回add函式

const complex& add(const complex& x)const

若我們以引用返回,將亡值物件會建立在add函式的棧幀中,然後返回將亡值位址,函式return結束該空間會被釋放、

若沒有引用,構建無名物件也就是將亡值物件會構建在主函式的空間中,這裡使用將亡值物件值給到c3是沒有問題的

我們檢視物件的構造與析構

class complex

complex(double r, double i) :real(r), im

complex(const complex& x):real(x.real),image(x.image)

~complex()

//complex add(const complex* const this,const complex &c)

complex add(const complex& x)const

void print() };

int main()

首先我們使用引用返回需要加上const修飾,這是因為我們返回將亡值在臨時空間具有常性,所以普通引用是不能進行返回的,需要使用常引用返回

const complex& add(const complex& x)const

我們發現對臨時物件的構建後馬上就進行析構,那麼是怎麼將資料拿出給到c3的?這個在最後我們進行分析

//complex operator+(const complex* const this,const complex &c)

complex operator+(const complex &c) const

這裡是不可以的,加號是乙個操作符,不能使用操作放作為有效的函式名稱;但是在c++中為了使這些操作符號能夠當作函式名,那麼我們需要在前面加上乙個關鍵字operator

//complex operator+(const complex* const this,const complex &c)

complex operator+(const complex &c) const

也就是告訴編譯器,加號是乙個有效的函式名,這就叫做運算子的過載;隨後我們之間使用 c3 = c1 + c2 就是可以的int main()

乙個物件,編譯器會給它有6個預設函式

我們再來看下面這個問題

//我們寫乙個賦值運算子過載

void operator=(const object& obj)

//返回型別為void,這樣不可以就不可以連等

//obja = objb = objc;

//obja = objb.operator=(objc);

//obja = operator=(&objb,objc); 返回的無型別,不能給obja賦值

且賦值函式不可以定義為const修飾

object& operator=(const object& obj)

obja = objb = objc;

//改寫

obja = objb.operator=(objc);

obja = operator=(&objb,objc);

obja.operator=(operator=(&objb,objc));

operator=(&obja,operator=(&objb,objc));

通過返回物件,就可以實現連等;並且我們可以通過引用返回,因為此物件的生存期並不受函式的影響,不會產生乙個臨時物件作為乙個過度

防止自賦值

若是我們將obja給obja賦值,也就是自賦值

obja = obja

operator=(&obja,obja);

我們就需要進行一步判斷

object& operator=(const object& obj)

return *this;

}我們通過這段**來看,與上面問題相同

object& operator=(const object& obj)

return *this;

}};object& fun(const object& obj)

int main()

我們在這裡希望通過引用返回,這裡return的臨時物件會構建在fun函式的棧幀中,並且在函式結束棧幀釋放,隨後呼叫賦值運算子過載,但是數值依舊是正確的

我們跟蹤這個被析構物件的位址,首先我們定位在fun函式的return obja;,隨後進入析構函式將我們的obja進行析構

接著執行到回到主函式進行賦值,接著進入賦值運算子過載,可以看到,這裡的obj位址與已被析構的obja位址相同

可以看到這個值依舊存在,依舊可以列印給出,這是因為vs2019的特殊性質造成的;我們每次執行程式會發現每次的物件位址都在變化,邏輯位址會隨機改變,被析構物件的棧幀不會被接下來的賦值運算子過載擾亂位址空間,所以即使我們引用返回的物件已經死亡依舊可以將數值正確返回

但是在vc中,我們得到的值會是隨機值,這是因為vc中每次執行程式位址都不會改變,當我們從fun函式退出進入賦值語句中,就會將原本儲存資料的位址擾亂,繼而變成了隨機值

儘管我們引用返回能夠將資料正確列印,但是該物件已經死亡,這是不安全的,所以我們一定不要以引用返回物件

vs2019具有乙個特點:當我們呼叫函式,若函式中沒有定義區域性變數或區域性物件時,該函式基本不對棧幀進行清掃

C 運算子過載詳解

1.運算子過載定義 c 中預定義的運算子的操作物件只能是基本資料型別。但實際上,對於許多使用者自定義型別 例如類 也需要類似的運算操作。這時就必須在c 中重新定義這些運算子,賦予已有運算子新的功能,使它能夠用於特定型別執行特定的操作。運算子過載的實質是函式過載,它提供了c 的可擴充套件性,也是c 最...

C 運算子過載詳解

list item過載運算子需要使用運算子函式,其宣告格式為operatorop argument list 要求op必須是c 的有效運算子,且不能是.等 1 過載後的運算子至少有乙個引數為自定義型別 2 使用運算子時不能違反運算子原來的句法規則,不能修改運算子的優先順序,不能建立新的運算子 3 不...

運算子過載詳解

1.運算子過載定義 c 中預定義的運算子的操作物件只能是基本資料型別。但實際上,對於許多使用者自定義型別 例如類 也需要類似的運算操作。這時就必須在c 中重新定義這些運算子,賦予已有運算子新的功能,使它能夠用於特定型別執行特定的操作。運算子過載的實質是函式過載,它提供了c 的可擴充套件性,也是c 最...