乙個類只有乙個例項物件,將類的建構函式、拷貝建構函式、賦值操作符函式設為私有,並且通過介面獲取唯一例項。
為什麼要用static,因為這乙個例項物件要起到全域性的作用,static將物件存在全域性變數區,生命週期伴隨整個程式。
在類載入的時候不初始化,等到需要的時候,才建立物件,這是一種時間換空間的方式
#include
using
namespace std;
class
singleton
//建構函式是私有的,這樣就不能在其它地方建立該例項
singleton
(const singleton&)=
delete
;//拷貝建構函式
singleton&
operator=(
const singleton&)=
delete
;static singleton* instance_ptr;
//定義乙個唯一指向例項的靜態指標,並且是私有的
public
:static singleton*
get_instance()
;//定義乙個公有函式,可以獲取這個唯一的例項,並且在需要的時候建立該例項。
~singleton()
};//static定義的資料成員必須在類外初始化,因為它是整個類的一部分,而不是屬於某個物件。
singleton* singleton::instance_ptr =
nullptr
;singleton* singleton::
get_instance()
intmain()
存在問題
①執行緒安全
當多執行緒獲取單例時有可能引發競態條件:第乙個執行緒在if中判斷 instance_ptr是空的,於是開始例項化單例;同時第2個執行緒也嘗試獲取單例,這個時候判斷instance_ptr還是空的,於是也開始例項化單例;這樣就會例項化出兩個物件,這就是執行緒安全問題的由來;
解決辦法:加鎖
②記憶體洩漏
注意到類中只負責new出物件,卻沒有負責delete物件,因此只有建構函式被呼叫,析構函式卻沒有被呼叫;因此會導致記憶體洩漏。
解決辦法: 使用智慧型指標,shared_ptr;
執行緒安全
#include
#include
// shared_ptr
#include
using
namespace std;
class
singleton
private
:singleton()
//建構函式是私有的,這樣就不能在其它地方建立該例項
static ptr instance_ptr;
//定義乙個唯一指向例項的靜態指標,並且是私有的
static mutex m_mutex;};
//static定義的資料成員必須在類外初始化,因為它是整個類的一部分,而不是屬於某個物件。
singleton::ptr singleton::instance_ptr =
nullptr
;mutex singleton::m_mutex;
singleton::ptr singleton::
get_instance()
return instance_ptr;
}int
main()
將 singleton* 改為 shared_ptr存在問題
① 使用智慧型指標會要求使用者也得使用智慧型指標,非必要不應該提出這種約束;
②使用鎖也有開銷;
③**量變多
即類產生的時候就建立好例項物件,這是一種空間換時間的方式
餓漢式的物件在類產生的時候就建立了,一直到程式結束才釋放。即物件的生存週期和程式一樣長,因此 該例項物件需要儲存在記憶體的全域性資料區,故使用static修飾。
定義了乙個建立物件的介面,封裝了具體產品物件的函式#include
using
namespace std;
class
singleton
;//建構函式是私有的,這樣就不能在其它地方建立該例項
singleton
(const singleton&)=
delete
;//拷貝建構函式
singleton&
operator=(
const singleton&)=
delete;~
singleton()
;public
:static singleton&
get_instance()
};intmain()
由工廠決定生產哪一種產品,選擇了什麼工廠就生產什麼樣的產品適用:需要建立的物件很多,導致物件的new操作多且雜時,使用簡單工廠模式,客戶只需傳入工廠類引數,對於如何建立物件不關心。由乙個工廠物件根據收到的訊息決定要建立哪乙個類的物件例項
缺點:擴充套件性非常差,新增產品的時候,需要修改工廠類
特點:#include
#include
using
namespace std;
typedef
enum producttypetag
producttype;
// here is the product class
class
product
//產品
;class
producta
:public product //產品a};
class
productb
:public product //產品b};
//工廠類
class
factory}}
;int
main
(int argc,
char
*ar**)
缺點:
特點:不止生產一類產品,提供乙個介面,可以建立多個產品族中的產品物件#include
using
namespace std;
// 產品抽象類
class
product
virtual
void
show()
=0;}
;// 產品a
class
producta
:public product};
// 產品b
class
productb
:public product};
// 抽象工廠類
class
factory};
// 具體工廠類 a /生產鏈
class
factorya
:public factory};
// 具體工廠類 b/生產鏈
class
factoryb
:public factory};
intmain()
缺點:同工廠方法模式一樣,新增產品時,都需要增加乙個對應的產品的具體工廠類。
#include
using
namespace std;
// 基類 衣服
class
clothe};
// 耐克衣服
class
nikeclothe
:public clothe};
// 基類 鞋子
class
shoes};
// 耐克鞋子
class
nikeshoes
:public shoes};
// 總廠
class
factory};
// 耐克生產者/生產鏈
class
nikeproducer
:public factory
clothe *
createclothe()
};intmain()
《面試準備》C 工廠模式
參考 簡單工廠模式 在工廠類做判斷,從而建立相應的產品,當增加產品時需要修改工廠類。簡單工廠模式 列舉 enum cartype 抽象類 多型 提高基類 class car 具體類 產品1 class bencicar public car 工廠方法模式抽象工廠類,只提供乙個介面,通過子類去擴充套件...
2012面試準備 2012 10 26面試準備
c 1 什麼純虛函式?首先,二者申明不一樣。virtual void test void 虛函式 virtual void test void 0 純虛函式 其次,如果乙個類包含了乙個純虛函式 哪怕只有乙個是純虛函式 那麼它就是乙個抽象類 就是不能生成具體的物件!但如果類中只包含虛函式,那麼是可以定...
設計模式 之 準備開始之前
它是一套理論,由軟體界的先輩們總結出的一套可以反覆使用的經驗,它可以提高 的可重用性,增強系統的可維護性,以及解決一系列的複雜問題。軟體的難處是如何把握需求的變更,變更不可控,只能擁抱變化 設計模式給出了指導,專家首先提出了 大設計原則。設計模式是對物件導向思想的深刻理解,對軟體設計方法和編碼經驗的...