賦值函數剖析
時間:2017-01-04作者:華清遠見
構造函數,拷貝構造函數,賦值函數和析構函數是C++類中基本的四大函數。當設計一個類時,要首先考慮這四大函數的寫法。若沒有提供顯式的實現,編譯器會產生默認的函數。若類中有指針成員,必須提供這四大函數的實現,否則容易出現內存錯誤。本文針對賦值函數進行了分析,包括其原型,調用場合,存在的必要性等方面。 1. 賦值函數原型 A& operator =( const A& other) { … … } 2. 調用場合
A a1(10); // 為a1調用構造函數 3.考察: 1) 為何首先檢查同一性? 答:為了防止自賦值 2) (a=b)=c或者a=(b=c)是否合法 答:合法 3) 若定義為void operator =(const A &a) 有何局限? 答:沒有了返回值,就不能實現a=b=c 這樣的鏈式復值。用法不夠靈活。 4) 賦值函數存在的必要性 答:以類String的兩個對象a,b為例,假設a.m_data的內容為“hello”,b.m_data的內容為“world”。現將a賦給b,缺省賦值函數的“位拷貝”意味著執行b.m_data = a.m_data。這將造成三個錯誤:一是b.m_data原有的內存沒被釋放,造成內存泄露;二是b.m_data和a.m_data指向同一塊內存,a或b任何一方變動都會影響另一方;三是在對象被析構時,m_data被釋放了兩次。 5) 若定義為A operator =(const A &a){...return *this;},有何局限? 答:若返回值改成了不是引用類型,則有兩個局限。 第一:對于a=(b=c), 操作仍然可以正常進行,但效率降低了。 因為此時的賦值函數會產生一個臨時對象,類似于 A tmp=*this. 假設b=c操作產生tmp1, 然后執行a=tmp1,該過程還會產生臨時對象tmp2。還會有tmp1, tmp2的析構。過程變得復雜許多。 第二:對于(a=b)=c, 操作不能以期望的方式進行。 假設a=b產生臨時對象tmp1, 然后tmp1=c, 這樣a不能獲得c的值,與常識不符。
相關資訊
發表評論
|