乙個類只能被例項化一次,產生乙個物件。
在類中,要構造乙個例項,就需要通過建構函式,所以為了防止在外部呼叫類的建構函式而構造例項,需要將建構函式的訪問許可權標記為protected或private;
並且需要提供給全域性訪問點,就需要在類中定義乙個static函式,返回在類內部唯一構造的例項。
懶漢式:在第一次用到類例項的時候才會去例項化,訪問量較小時,採用懶漢式,以時間換空間。並不安全,因為例項化並不是原子操作,可能在例項化的過程中,在給指標賦值之前,cpu切換執行緒導致產生多個物件。
餓漢式:在單例類定義的時候就進行例項化。訪問量較大、執行緒較多時,採用餓漢式,以空間換時間。執行緒安全,因為一開始就例項化了。
懶漢式:
class single
pthread_mutex_unlock(&mtx);
} return p;
}private:
static single* volatile p;
single(){}
};pthread_mutex_t single::mtx = pthread_mutex_initializer; 建立互斥鎖
***************懶漢與餓漢的區別就在於這個靜態成員變數例項化的位置不一樣***************
single* single::p = null; 靜態成員變數初始化 懶漢式在此處例項化
int main()
{ single* tmp = single::get_single(); 用作用域加成員函式名呼叫靜態函式。
single* tmp1 = single::get_single();
cout 《解決幾個問題:
1、為什麼用靜態函式,靜態成員變數?
呼叫類裡的函式需要先構造物件,有物件才能呼叫類內成員方法。但這個方法肯定不適合單例模式。而另一種方法就是靜態函式,可以使用類名直接呼叫。而靜態函式只能呼叫靜態成員方法。
2、為什麼加雙重檢查?
咱們從內向外分析,首先為了滿足單例模式的要求,也就是說p建立了物件,之後就不能再建立了,外面就需要加一層判斷,保證在單執行緒的情況下可以順利實現單例。但這樣也僅僅在單執行緒下滿足,如果多執行緒,由於cpu時間片輪轉,很可能導致在賦給p途中被截斷,從而另乙個程序也建立了物件,為避免這種情況的發生,需要在外面加一互斥鎖。但加鎖的操作是由核心完成的,也就是說每次檢查是否持鎖都需要陷入核心。這種情況我們發現對於單執行緒又發生了不友好,單執行緒沒有必要取鎖解鎖消耗時間和資源。所以我們加了最外面的一層判斷,如果p已經不是null,我們直接跳過,不再進行鎖操作。
3、私有靜態成員變數volatile是個啥?
volatile:
1、防止多執行緒對共享變數進行執行緒快取操作,乙個執行緒修改了共享變數,另乙個執行緒不能及時看到。
2、防止編譯器對涉及value操作的**進行指令重排序
設計模式(C ) 05介面卡模式
推薦閱讀 自然界有一條規則 適者生存。意思是生物要使用自然界的變化 在程式界中則需要新環境呼叫現存物件。那麼,如何在新環境中呼叫 現存的物件 呢?採用介面卡模式可以解決。介面卡模式使得新環境中不需要去重複實現已經存在了的實現,而很好的把現有的物件 指原來環境中的現有物件 加入到新環境中來使用。介面卡...
C05 變數屬性
6.總結 語法 property type var name 示例 intmain void f include register int g val error int main include int g val 全域性變數,可以在程式的任意位置訪問 static int g sval 靜態全域...
設計模式05 單例模式
單例模式是一種物件建立型模式,使用單例模式,可以保證為乙個類只生成唯一的例項物件。也就是說,在整個程式空間中,該類只存在乙個例項物件。其實,gof對單例模式的定義是 保證乙個類 只有乙個例項存在,同時提供能對該例項加以訪問的全域性訪問方法。在應用系統開發中,我們常常有以下需求 在多個執行緒之間,比如...