C++特殊類的設(shè)計(jì)

      網(wǎng)友投稿 945 2025-03-31

      @TOC

      零、前言

      本章我們主要講解學(xué)習(xí)特殊類的設(shè)計(jì)方式

      一、不能被拷貝

      想要讓一個類禁止拷貝,只需讓該類不能調(diào)用拷貝構(gòu)造函數(shù)以及賦值運(yùn)算符重載即可

      方式1:

      C++98下,私有化拷貝構(gòu)造函數(shù)與賦值運(yùn)算符重載并且只聲明不定義

      示例代碼:

      class NoCopy { public: NoCopy() :_a(0) {} private: NoCopy(const NoCopy& oh);//只聲明不用實(shí)現(xiàn)(C98) NoCopy& operator=(const NoCopy& oh) ; int _a; };

      解釋:

      設(shè)置成私有:如果只聲明沒有設(shè)置成private,用戶自己如果在類外定義了,就可以不能禁止拷貝了

      只聲明不定義:不定義是因?yàn)樵摵瘮?shù)根本不會調(diào)用,定義了其實(shí)也沒有什么意義

      方式二:

      C++特殊類的設(shè)計(jì)

      C++11下,在拷貝構(gòu)造函數(shù)與賦值運(yùn)算符重載函數(shù)后跟上=delete

      示例代碼:

      class NoCopy { public: NoCopy() :_a(0) {} private: NoCopy(const NoCopy& oh)=delete;//C++11 NoCopy& operator=(const NoCopy& oh)=delete; int _a; };

      注:C++11擴(kuò)展delete的用法,delete除了釋放new申請的資源外,如果在默認(rèn)成員函數(shù)后跟上=delete,表示讓編譯器刪除掉該默認(rèn)成員函數(shù),即不能被調(diào)用

      示圖:

      二、只能在堆上創(chuàng)建對象

      方式1:

      構(gòu)造函數(shù)私有化,棧上創(chuàng)建的對象銷毀調(diào)用不了析構(gòu)函數(shù)而報錯;給定特有的銷毀函數(shù),對堆上變量進(jìn)行銷毀

      示例代碼:

      class OnlyHeap { public: void Destory() { delete this;//類函數(shù)里調(diào)用delete cout << "delete" << endl; } private: ~OnlyHeap()//析構(gòu)函數(shù)私有化,棧上創(chuàng)建的對象銷毀不能調(diào)用會報錯 { cout << "~OnlyHeap" << endl; } int _a; };

      解釋:

      構(gòu)造函數(shù)私有化:對于棧上創(chuàng)建的對象銷毀調(diào)用不了析構(gòu)函數(shù)會報錯,也就是間接的不讓創(chuàng)建棧對象

      給定特有的銷毀函數(shù):在類函數(shù)里可以訪問私有成員,進(jìn)行delete時能夠使用私有的析構(gòu)函數(shù)并進(jìn)行釋放對象

      方式2:

      私有化構(gòu)造函數(shù),拷貝構(gòu)造。防止別人調(diào)用拷貝在棧上生成對象;提供靜態(tài)的成員函數(shù),在該靜態(tài)成員函數(shù)中完成堆對象的創(chuàng)建

      示例代碼:

      class OnlyHeap { public: static OnlyHeap* ObjCreat()//提供對象創(chuàng)建的靜態(tài)成員方法 { cout << "new OnlyHeap" << endl; return new OnlyHeap; } private: OnlyHeap()//禁止直接調(diào)用構(gòu)造 :_a(0) { cout << "OnlyHeap" << endl; } OnlyHeap(const OnlyHeap& oh);//防止拷貝 OnlyHeap& operator=(const OnlyHeap& oh); int _a; };

      解釋:

      私有化構(gòu)造函數(shù)/拷貝構(gòu)造:防止別人調(diào)用拷貝在棧上生成對象

      提供靜態(tài)創(chuàng)建對象函數(shù):在該靜態(tài)成員函數(shù)中完成堆對象的創(chuàng)建,類里的函數(shù)能夠調(diào)用私有化的構(gòu)造函數(shù)

      注:一定是靜態(tài)的成員函數(shù),靜態(tài)成員函數(shù)不需要依賴對象進(jìn)行調(diào)用,普通的成員函數(shù)則不行

      示圖:

      三、只能在棧上創(chuàng)建對象

      方式1:

      顯示聲明并私有化operator new/operator delete函數(shù)

      示例代碼:

      class OnlyStack { public: OnlyStack() :_a(0) { cout << "Onlystack" << endl; } private: //顯示成私有化避免調(diào)用 void* operator new(size_t size); void operator delete(void* p); int _a; };

      解釋:

      顯示私有化:顯示是為了讓new的時候找到對象專屬的operator new函數(shù),私有化則是為了不讓operator new函數(shù)不被成功使用,避免調(diào)用

      注:唯一的缺點(diǎn)是不能避免在靜態(tài)區(qū)創(chuàng)建對象

      示圖:

      方式2:

      私有化構(gòu)造函數(shù),提供特定創(chuàng)建對象的靜態(tài)成員函數(shù)

      示例代碼:

      class OnlyStack { public: static OnlyStack ObjCreat() { return OnlyStack();//類里進(jìn)行調(diào)用構(gòu)造 } private: OnlyStack()//構(gòu)造私有化,避免new調(diào)用 :_a(0) { cout << "OnlyStack" << endl; } int _a; };

      解釋:

      私有化構(gòu)造函數(shù):new一個對象=調(diào)用類的構(gòu)造函數(shù)+operator new(),這里避免new調(diào)用創(chuàng)建對象

      四、不能被繼承的類

      方式1:

      在C++98下,私有化構(gòu)造函數(shù),提供特定的創(chuàng)建靜態(tài)成員函數(shù)

      示例:

      class NonInherit { public: static NonInherit GetInstance() { return NonInherit(); } private: // 構(gòu)造函數(shù)私有 NonInherit() {} }; class Derive : NonInherit {};

      解釋:

      C++98 這種方式不夠直接,這里是可以繼承的,但是Derive不能創(chuàng)建對象,因?yàn)镈erive的構(gòu)造函數(shù)必須要調(diào)用父類NonInherit構(gòu)造,但是NonInherit的構(gòu)造函數(shù)私有了,私有在子類不可見,那么這里繼承不會報錯,繼承的子類創(chuàng)建對象會報錯

      方式2:

      final修飾類,表示該類不能被繼承

      示例代碼:

      class NoInherit final { }; class Derive : NoInherit {};

      示圖:

      五、只能創(chuàng)建一個對象

      設(shè)計(jì)模式的概念:

      設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過分類的、代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)

      使用設(shè)計(jì)模式的目的:

      為了代碼可重用性、讓代碼更容易被他人理解、保證代碼可靠性;設(shè)計(jì)模式使代碼編寫真正工程化

      單例模式:

      一個類只能創(chuàng)建一個對象,即單例模式,該模式可以保證系統(tǒng)中該類只有一個實(shí)例,并提供一個訪問它的全局訪問點(diǎn),該實(shí)例被所有程序模塊共享

      比如:

      在某個服務(wù)器程序中,該服務(wù)器的配置信息存放在一個文件中,這些配置數(shù)據(jù)由一個單例對象統(tǒng)一讀取,然后服務(wù)進(jìn)程中的其他對象再通過這個單例對象獲取這些配置信息,這種方式簡化了在復(fù)雜環(huán)境下的配置管理

      單例模式有兩種實(shí)現(xiàn)模式:

      餓漢模式和懶漢模式

      1、餓漢模式

      當(dāng)程序啟動時就創(chuàng)建一個唯一的實(shí)例對象

      示例代碼:

      class Singleton { public: static Singleton& GetInstance()//獲取實(shí)例地址 { return _s; } vector _v;//可以選擇私有也可以選擇公有 private: Singleton();//構(gòu)造私有化,禁止隨意構(gòu)造 //delete拷貝構(gòu)造和賦值函數(shù),防拷貝賦值 Singleton(const Singleton& s) = delete; Singleton& operator=(const Singleton& s) = delete; static Singleton _s;//在類里的變量都是聲明,在cpp文件中進(jìn)行定義 };

      解釋:

      類里面的成員變量只是聲明,而靜態(tài)成員對象需要在類外進(jìn)行定義,并且不能在.h文件中定義,如果多個.cpp文件包含該頭文件,那么則會報重復(fù)定義的錯誤

      效果:

      優(yōu)勢:

      實(shí)現(xiàn)簡單

      劣勢:

      如果單例對象構(gòu)造十分耗時或者占用很多資源,比如加載插件啊, 初始化網(wǎng)絡(luò)連接啊,讀取文件啊等等,而有可能該對象程序運(yùn)行時不會用到,那么也要在程序一開始就進(jìn)行初始化,就會導(dǎo)致程序啟動時非常的緩慢

      對于多個單例類的如果具有依賴關(guān)系的話,則無法進(jìn)行控制定義順序(靜態(tài)變量)

      2、懶漢模式

      懶漢模式則是需要的時候在第一次調(diào)用的時候進(jìn)行創(chuàng)建

      示例代碼:

      class Singleton { public: //提供獲取對象以及釋放對象的靜態(tài)方法 static Singleton& GetInstance() { //提高效率,避免多次鎖住及解鎖 if (_s == nullptr) { //保證線程安全 _m.lock();//鎖住 if (_s == nullptr) { _s = new Singleton; } _m.unlock();//解鎖 } return *_s; } static void DelInstance() { //提高效率,避免多次鎖住及解鎖 if (_s != nullptr) { //保證線程安全 _m.lock();//鎖住 if (_s != nullptr) { delete _s; _s = nullptr; } _m.unlock();//解鎖 } } vector _v; private: Singleton() {};//要有函數(shù)體,否則只是聲明,當(dāng)new的時候找不到對應(yīng)的實(shí)體 Singleton(const Singleton& s) = delete; Singleton& operator=(const Singleton& s) = delete; static Singleton* _s;//儲存實(shí)例對象地址 static mutex _m;//互斥鎖 };

      解釋:

      對于懶漢模式需要注意的是要保證線程安全,當(dāng)多個進(jìn)行調(diào)用GetInstance()/DelInstance()時,可能多次進(jìn)行new和delete,可能造成數(shù)據(jù)的丟失

      效果:

      優(yōu)勢:

      無啟動負(fù)載;可以自由控制多個單例類的定義順序

      劣勢:

      實(shí)現(xiàn)復(fù)雜

      C++

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:wps突然未響應(yīng),文件未保存,等待響應(yīng)很久后自己退出,而且未保存文件。
      下一篇:為什么 播放不了音頻(為什么會痛經(jīng))
      相關(guān)文章
      亚洲偷自精品三十六区| 国产亚洲AV手机在线观看| 国产亚洲色婷婷久久99精品| 色婷婷六月亚洲综合香蕉| 亚洲日韩精品国产3区| 亚洲字幕AV一区二区三区四区| 亚洲色图综合网站| 亚洲成人免费网址| 亚洲av永久无码精品三区在线4| 91亚洲自偷在线观看国产馆| 亚洲成人一级电影| 亚洲资源最新版在线观看| 亚洲欧洲春色校园另类小说| 亚洲综合久久1区2区3区| 亚洲欧洲精品在线| 亚洲乱码卡三乱码新区| 亚洲香蕉久久一区二区| 亚洲中文字幕乱码一区| 色偷偷噜噜噜亚洲男人| 亚洲国模精品一区 | 亚洲中久无码不卡永久在线观看| 亚洲国产精品无码久久青草| 国产成人精品日本亚洲专区| 亚洲日本乱码在线观看| 亚洲国产精品VA在线观看麻豆| 久久精品亚洲视频| 亚洲神级电影国语版| 亚洲人配人种jizz| 亚洲av无码无线在线观看| 亚洲av日韩av欧v在线天堂| 中文字幕亚洲无线码| 久久青青草原亚洲AV无码麻豆| 亚洲国产另类久久久精品小说| 亚洲精品国产精品乱码不卡√| 亚洲成人精品久久| 亚洲av永久综合在线观看尤物| 亚洲欧美日韩综合久久久久| 亚洲av无码专区青青草原| 亚洲毛片不卡av在线播放一区| 亚洲色偷拍另类无码专区| 久久精品国产亚洲AV香蕉|