C 05 單例模式

2021-08-30 21:47:44 字數 1491 閱讀 2802

乙個類只能被例項化一次,產生乙個物件。

在類中,要構造乙個例項,就需要通過建構函式,所以為了防止在外部呼叫類的建構函式而構造例項,需要將建構函式的訪問許可權標記為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對單例模式的定義是 保證乙個類 只有乙個例項存在,同時提供能對該例項加以訪問的全域性訪問方法。在應用系統開發中,我們常常有以下需求 在多個執行緒之間,比如...