什麼時候需要定義拷貝建構函式【轉】
當沒有定義拷貝建構函式時,物件值傳遞時是位拷貝,但是通常情況下,位拷貝已經能滿足我們的要求,是我們不必自己定義拷貝建構函式。
但是什麼時候需要自己定義呢?
這裡有個簡單的規則:如果你需要定義一個非空的解構函式,那麼,通常情況下你也需要定義一個拷貝建構函式。
像我們常練習去寫一個string類時,會去寫個普通構造,拷貝構造,過載賦值運算子=,因為裡面有個指標變數char * pBuff,在解構函式中,一般都會將該指標置空,這樣的析構就是個非空的解構函式。
如果你定義拷貝建構函式時遇到這樣的錯誤:
no copy constructor available or copy constructor is declared 'explicit'
意味著你的拷貝建構函式的引數不是const 。
而且拷貝建構函式是不能加explicit關鍵字的! 何謂拷貝?在這裡,即型別相同的物件才能稱為“拷貝”,既然型別相同,那就不存在什麼隱式轉換的問題! 只有建構函式的引數型別(單一引數或多引數帶有預設值)與當前類型別不同時,才有隱式轉換問題。
explicit是用來防止外部非正規的拷貝構造的。要想不存在傳值的隱式轉換問題,就可以在變數前加上explicit 關鍵字。
Q:為什麼拷貝建構函式的引數型別一般都是const ?
A:因為複製建構函式是用引用方式傳遞複製物件,引用方式傳遞的是地址,因此在建構函式內對該引用的修改會影響源物件。而你在用物件a1構造a2時,自然不希望複製建構函式會改變a1的內容,因此要防止複製建構函式內部修改該引用,所以用const宣告。
class A { int x; A(int c){x=c;}; A(const A & c){x=c.x}; // 複製建構函式 }
void main() { class A a1(10); class A a2(a1); // 在用a1構造a2的時候,你當然不希望a1會被改變。 } Q:在拷貝建構函式中為什麼可以訪問引用物件的私有變數? A:所謂訪問許可權(如public,private),是對“類”來說的,不是對“物件”來說的,private訪問許可權是其它類不能訪問,而非這個類的不同物件不能訪問。其實這也非常合理,類是自己設計的,當然自己也就知道類的內部結構,所以沒有必要對自己也進行類的“封裝”。 --------------------------------------------------------------- 當一個函式想訪問某個類的私有成員時,需要在要訪問的這個類的定義中宣告這個函式是它的友元。(個人建議:儘量不要去使用友元,破壞了封裝性) 而當這個函式就屬於這個類本身的時候,自然就不用多此一舉了. 就是說,一個物件的某個函式可以訪問同一個類其他物件的私有成員。 這種問題除了在拷貝構造函數出現以外一般不會那樣使用。 --------------------------------------------------------------- 結果很顯然,如果不能訪問,那麼私有成員的存在就沒有了意義。而對於成員函式中允許訪問物件的資料成員,一方面保證了安全性與封裝性,另一方面提供方便的操作。第一句話的解釋,就是承認只有成員函式可以訪問私有成員,這裡不涉及友元及派生。這樣一來,安全性仍然得到了保證,也完成了封裝工作。對於第二句話,試想,如果都得靠介面來實現資料傳送,那麼操作是否極為不便?既然處於成員函式中,已經保證了足夠的安全和封裝性,那麼這裡如果還得藉助介面,就有些不合情合理了。作為對資料成員的靈活處理,設計者允許在成員函式中訪問物件的私有成員,為使用者提供了很大的方便。這同時也反映了語言的靈活性和原則性。 --------------------------------------------------------------- 私有的許可權不是對於類中的各個成員說的,所以本類的成員可以訪問本類的私有成員,但是一個物件不是這個類的成員,所以不能訪問私有成員,這就是為什麼需要getxxx()介面的原因。 --------------------------------------------------------------- C++的封裝是針對程式設計或作的,所以到達類的層次,而類的例項是執行狀態,不再功能範疇之類,從使用角度來說,也無須這麼做 --------------------- 作者:SurgePing 來源:CSDN 原文:https://blog.csdn.net/suxinpingtao51/article/details/36890809?utm_source=copy 版權宣告:本文為博主原創文章,轉載請附上博文連結!