前段時間要實習一個充值接口,創建了一個類(就叫類A好了),這個類A要和另外3個類進行交互,3個類對類A修改的數據是對其他類可見的。這種情況我想到了3個方法:
1.static 靜態成員,靜態成員為該類的所有實例所共享,3個類中各自創建一個類A的對象,它們對靜態成員的修改對其他類可見。
2.全局變量,類A的頭文件中添加 extern classA g_classA; 源文件中添加 classA g_classA; 3個類中添加頭文件后直接通過g_classA //這種不推薦
3.單例模式
使用單例模式替代全局變量,3個類對類A的函數訪問都是對類A的唯一實例的數據訪問,修改對其他類自然可見了。單例模式是使用全局變量的常見替代方法。
下面是轉自一位前輩的單例實現模式的總結,第三種實現實在太精彩了,只能用"nice catch"來形容!
——————————華麗的分割線——————————
轉自:http://lwzy-crack.blog.163.com/blog/static/9527204220091068526135/
C++中的單例模式
單例模式很有用,使用單例模式,保證一個類僅有一個實例,並提供一個訪問它的全局訪問點,該實例被所有程序模塊共享。
但是在程序的開發過程中我們總是遇到一些問題,而這些問題主要集中在單例類的消毀過程中,普通使用的單例模式的類如下:
class Singleton:
{
// 其它成員
public:
static Singleton * GetInstance()
{
if (m_pInstance == NULL)
m_pInstance = new Singleton();
return m_pInstance;
}
private:
Singleton(){};
static Singleton * m_pInstance;
}
可是這個類在什么時候調用它的析構函數呢,我們怎么消毀它。提供一個公用的destroy函數來進行它的消毀嗎,這很不美觀。最后我就在網上找到了如果下的代碼處理了這個問題:
class Singleton:
{
// 其它成員
public:
static Singleton * GetInstance(){...}
private:
Singleton(){};
static Singleton * m_pInstance;
class CGarbo // 它的唯一工作就是在析構函數中刪除Singleton的實例
{
public:
~CGarbo(){
if (Singleton::m_pInstance)
delete Singleton::m_pInstance;
}
};
static CGarbo Garbo; // 定義一個靜態成員,在程序結束時,系統會調用它的析構函數
}
這是非常好的方法,靜態成員對象 Garbo 在析構時會自動的消毀單例,我們不用再擔心這個問題了。
但是添加一個類的靜態對象,總是讓人不太滿意,所以有人用如下方法來重現實現單例和解決它相應的問題,代碼如下:
class Singleton:
{
// 其它成員
public:
static Singleton &GetInstance(){
static Singleton instance;
return instance;
}
private:
Singleton(){};
}
使用局部靜態變量,非常強大的方法,完全實現了單例的特性,而且代碼量更少,也不用擔心單例消毀的問題。
在后期的項目中我全使用了這種方法,可是在項目的開發過程中還是出現了問題,當如下方法使用單例時問題來了,
Singleton singletion = Singleto::GetInstance();
這么做就產生了一個類拷貝的問題,這就為背了單例的特性。
產生這個問題的原因在於,編譯器會為類生成一個默認的構造函數,來支持類的拷貝。
最后沒有辦法,我們要禁止類拷貝和類賦值,禁止程序員用這種方式來使用單例,當時領導的意思是GetInstance()函數返回一個指針而不是返回一個引用,函數代碼改為如下:
static Singleton *GetInstance(){
static Singleton instance;
return &instance;
}
可我總是感覺不好,為什么不讓編譯器不這么干呢。這時我才想起可以顯式的聲明類拷貝的構造函數,和重載=操作符,新的單例類如下:
class Singleton:
{
// 其它成員
public:
static Singleton &GetInstance(){
static Singleton instance;
return instance;
}
private:
Singleton(){};
Singleton(const Singleton&);
Singleton & operate = (const Singleton&);
}
關於Singleton(const Singleton&);和Singleton & operate = (const Singleton&);函數,我們要聲明成私用的,並且只聲明不實現。這樣子后如果用上面的方式來使用單例時,不管是在友元類中還是其它的,編譯器都是報錯。
不知道這樣的單例類是否還會有問題,但在程序中這樣子使用已經基本沒有問題了。
——————————華麗的分割線——————————