看過Effective C++的人都知道,為了防止一個(gè)class被copying,而且將錯(cuò)誤提前到編譯期,基本有兩種方法:
1. 將這個(gè)類的copy構(gòu)造函數(shù)和copy assignment操作符都聲明為private而且沒有定義。示例代碼如下:
1?class?SomeClass?{
2?????...
3?private:
4?????//只有聲明
5?????SomeClass(const?SomeClass&);
6?????SomeClass&?operator=(const?SomeClass&);
7?};
2. 專門設(shè)計(jì)一個(gè)為了阻止copying動(dòng)作而設(shè)計(jì)的base class,這個(gè)base class相當(dāng)簡(jiǎn)單:
1?Uncopyable?{
2?protected:?//允許derived對(duì)象構(gòu)造和析構(gòu)
3?????Uncopyable()?{}
4?????~Uncopyable()?{}
5?private:?//阻止copying
6?????Uncopyable(const?Uncopyable&);
7?????Uncopyable&?operator=(const?Uncopyable&);
8?};
為了阻止某個(gè)對(duì)象如SomeClass被copying,我們唯一需要做的就是繼承自Uncopyable:
1?SomeClass?:?private?Uncopyable?{
2?????...
3?};
第2種方案貌似很完美,在大多數(shù)情況下也工作的很好,甚至boost庫也廣泛采用了(boost庫中的叫noncopyable)。當(dāng)然了,因?yàn)閁ncopyable不含任何數(shù)據(jù),符合EBO(empty base class optimization,空白基類最優(yōu)化)資格,但由于它總是扮演base class,因此有可能導(dǎo)致多重繼承,而EBO一般只在單繼承下才可行,編譯器通常不會(huì)對(duì)有多個(gè)base class的derived classes施行EBO。
如果你不想導(dǎo)致多重繼承,不管是從性能上還是書寫代碼上,比如SomeClass繼承自某個(gè)base class,你可能會(huì)寫如下代碼:
1?class?SomeClass?:?public?BaseClass,?private?Uncopyable?{
2?????...
3?};
這讓人很不爽,要是你跟我一樣懶,你肯定也不會(huì)愿意采用第一種方案,因?yàn)槟且馕吨銜?huì)在每一個(gè)不想被copying的class里都加上那三行代碼。
如果用Macro就很簡(jiǎn)單了,即靈活又方便:
1?#define?CLASS_UNCOPYABLE(classname)?\
2?????private:?\
3?????classname(const?classname&);?\
4?????classname&?operator=(const?classname&);
現(xiàn)在SomeClass只需寫成這樣:
1?class?SomeClass?{
2?????CLASS_UNCOPYABLE(SomeClass)
3?????...
4?};
不僅省事而且靈活!!!