歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C++如何拒絕對象的copy

C++如何拒絕對象的copy

日期:2017/3/1 9:43:01   编辑:Linux編程

<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