歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

C++如何拒絕對象的copy

<Effective C++>中的一個條款,如果是想要阻止一個對象的復制或是copy assignment操作應該怎麼做呢?
 
class HomeForSale {};
 
HomeForSale h1;
 
HomeForSale h2;
 
HomeForSale h3(h1);      //企圖調用h3的copy構造函數克隆出一份h1
 
h1 = h2;                          //企圖調用copy assignment操作將h2對象完好的賦值給h1
 
以上兩個例子均是對一個對象的復制或是賦值,兩者說法不同,語法不同,調用時機不同,但是內部實現卻是差不多的。如題,我們要避免的就是以上這兩種例子的出現。
 
想要阻止這一類代碼的編譯不是很直觀的事情,通常來說,我們不想讓對象有某個操作,就不要聲明與實現相應的函數就是了,這對一般的函數來說確實是可以的,但是我們要阻止的兩個函數有一些特殊。這兩個函數即使我們不顯示的聲明與實現,只要我們的代碼在執行時有這兩個中的一個需求,編譯器都會為我們實現一份編譯器版本。如何是好呢?
 
答案是:編譯器為用戶自動生成的函數均為public函數,我們可以顯示的將這兩個函數聲明為private,又因為我們不會去調用他們,所以只是將他們聲明為private,而不去實現他們。這麼做就達到了兩個目的:1顯示的聲明為private,編譯器得知用戶手動的聲明的函數,就不會再自作主張為我們創建編譯器版本了,也就不會有public相應函數了。2不實現,因為我們並不會去調用他們,所以實現了反而是畫蛇添足了。
 
類的成員函數或是類的友元函數都有權利去訪問類的私有域,但是這時候調用他們的話,會收到一個鏈接錯誤,因為我們並沒有實現出這兩個函數。我們能做的就是,盡可能的避免調用他們了。

C++ Primer Plus 第6版 中文版 清晰有書簽PDF+源代碼 http://www.linuxidc.com/Linux/2014-05/101227.htm

讀C++ Primer 之構造函數陷阱 http://www.linuxidc.com/Linux/2011-08/40176.htm

讀C++ Primer 之智能指針 http://www.linuxidc.com/Linux/2011-08/40177.htm

讀C++ Primer 之句柄類 http://www.linuxidc.com/Linux/2011-08/40175.htm
 
這樣子一來,我們前面的那幾句代碼:
 


HomeForSale h1;            //沒有可用的構造函數
 
HomeForSale h2;            //同上
 
HomeForSale h3(h1);      //企圖調用h3的copy構造函數克隆出一份h1,私有函數無法調用
 
h1 = h2;                          //企圖調用copy assignment操作將h2對象完好的賦值給h1,私有函數無法調用
 

 

將鏈接期錯誤轉到編譯期是可行的,就是設計基類。
 
class Uncopyable
 {
 protected:
 Uncopyable() {}
 ~Uncopyable() {}  //即使是基類也沒有將其析構函數設計為virtual,是這裡沒有動態釋放對象的需求。
 private:
 Uncopyable(const Uncopyable &c);
 Uncopyable& operator= (const Uncopyable &c);
 };
 
class HomeForSale:public Uncopyable
 {
 //這時候類中就不需求聲明copy構造函數,和copy assignment操作符了
 };
 

這裡即使是成員函數或是友元函數嘗試拷貝HomeForSale,編譯器便試著生成一個copy構造函數或是copy assignment操作符,會去調用其基類的相應函數,因為基類中是private,所以編譯器生成失敗。拋出編譯期錯誤,及早的發現了問題。

Copyright © Linux教程網 All Rights Reserved