实现一个无法被继承的C++类
原文地址:http://blog.csdn.net/lazy_tiger/article/details/2224899
一個類不能被繼承,也就是說它的子類不能構(gòu)造父類,這樣子類就沒有辦法實(shí)例化整個子類從而實(shí)現(xiàn)子類無法繼承父類。我們可以將一個類的構(gòu)造函數(shù)聲明為私有,使得這個類的構(gòu)造函數(shù)對子類不可見,那么這個類也就不能繼承了。但是,這引出一個問題,客戶程序豈不是也無法實(shí)例化這個類了?OK,讓我們參考一下Singleton模式,用一個static函數(shù)來幫助創(chuàng)建這個類的實(shí)例,問題就解決了!
?
1 class CParent 2 { 3 private: 4 CParent(int v){m_v = v;} 5 ~CParent(){} 6 int m_v; 7 static CParent * m_instance; 8 public: 9 void fun(){cout << "The value is: " << m_v << endl;} 10 static CParent * getInstance(int v); 11 }; 12 CParent * CParent::m_instance = NULL; 13 CParent * CParent::getInstance(int v) 14 { 15 m_instance = new CParent(v); 16 return m_instance; 17 }?
這是一個有效的方法,但是static函數(shù)創(chuàng)建出來的實(shí)例必然是static的。而且,這個類不能像普通的類那樣構(gòu)建對象,比如:
?
1 CParent c; // impossible換個思路考慮一下,友元不也是不能被繼承的么?我們可以把類的構(gòu)造函數(shù)定義為private的同時,定義友元函數(shù)來幫助構(gòu)造類的實(shí)例。
class CParent { private: CParent(int v){m_v = v;} ~CParent(); int m_v; public: void fun(){cout << "The value is: " << m_v << endl;} friend CParent * getInstance(int v); }; CParent * getInstance(int v) { CParent * pinstance = new CParent(v); return pinstance; }這個類也是不能被繼承的,但是出現(xiàn)的問題和前面一樣:我們還是不能像對普通類那樣對待這個類。
現(xiàn)在設(shè)想一下,有一個CParent類,我們不希望他能夠被繼承。在友元不能被繼承的思路指引下,我們要考慮讓CParent的友元屬性不能被繼承。假設(shè)有一個輔助類CNoHeritance,CParent是CNoHeritance類的友元。還要假設(shè)一個CChild類,它試圖去繼承CParent類(如果它有這個能耐的話)。
先把CNoHeritance類的構(gòu)造函數(shù)定義成private,然后將CParent聲明為CNoHeritance的友元類。同時CParent繼承了CNoHeritance類。到目前為止,CNoHeritance除了CParent類以外,誰也無法對它進(jìn)行訪問和實(shí)例化。CChild因?yàn)闊o法繼承CParent的友元特性,所以CChild無法對CNoHeritance直接進(jìn)行實(shí)例化(但是可以通過CParent)。
到目前為止,CParent還是可以被繼承的。這是一個trick.讓我們整理一下思路,下面的圖說明了CNoHeritance, CParent和CChild三個類之間的關(guān)系。
?
如果我們讓CParent類虛繼承CNoHeritance類,根據(jù)虛繼承的特性,虛基類的構(gòu)造函數(shù)由最終的子類負(fù)責(zé)構(gòu)造。因此CChild如果要想繼承CParent,它必須能夠構(gòu)造CNoHeritance,這是不可能的!因此,我們的CParent也就終于成為了一個無法繼承的類。
?
1 class CNoHeritance 2 { 3 private: 4 CNoHeritance(){} 5 ~CNoHeritance(){} 6 friend class CParent; 7 }; 8 class CParent : virtual public CNoHeritance 9 { 10 public: 11 CParent(int v){m_v = v;} 12 ~CParent(){}; 13 private: 14 int m_v; 15 public: 16 void fun(){cout << "The value is: " << m_v << endl;} 17 }; 18 class CChild : public CParent 19 { 20 public: 21 CChild():CParent(10){} 22 ~CChild(){} 23 };需要注意的是,我們這里引入的CNoHeritance類對整個程序而言,只引入了Private的構(gòu)造函數(shù)和析構(gòu)函數(shù),所以不會因?yàn)榭赡艿牧庑卫^承帶來二義性.
?
?
?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/theCambrian/p/3501806.html
總結(jié)
以上是生活随笔為你收集整理的实现一个无法被继承的C++类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Google Maps API 简易教程
- 下一篇: Unity2D:简单人物纸娃娃换装实现(