C 靜態成員與單例模式

2021-07-03 18:18:24 字數 3386 閱讀 3449

什麼是靜態成員

靜態成員變數、靜態成員函式、靜態類

在乙個類中,往往需要那麼乙個變數需要被各個物件共享,例如銀行中的活期存款利率,如果需要乙個變數去統計某個類中存在的物件個數,那麼這個變數也是每個物件都共享了。這個變數可以是個全域性變數,但如果定義成全域性變數,就會影響類的封裝性,因為我們可以在普通的**中就可以輕鬆的去修改它。那麼這時候就可以在類中宣告乙個靜態成員變數變數。這樣不僅能有效防止使用者意外的去修改了這麼乙個變數,更能突出類的自洽性。

靜態成員並不依賴於物件,屬於類而非物件的

靜態成員變數不包含在物件例項中,具有程序級的生命週期。(靜態成員存放於全域性區,程式執行前就已經存在)

靜態成員函式沒有this指標,也沒有常屬性。(this指向的是正在構造的物件 或者 已經存在的物件,靜態成員屬於類,不屬於物件更不依賴於物件,所以不存在this指標)

靜態成員依然受類作用域和訪問控制限定符的約束。

所以我們可以把靜態成員變數看做乙個受作用域和訪控屬性影響的全域性變數。

靜態成員變數的使用

靜態成員變數的定義和初始化,只能在類的外部而不能在建構函式中進行。

語法: 物件.靜態成員 / 類名::靜態成員

/*

靜態成員

*/#include using namespace std;

class account

//檢視利率

static double getrate(void)

//建構函式

account(string name, int passwd, double balance = 0) :

m_id(1000 + s_size++), m_name(name), m_passwd(passwd), m_balance(balance)

//列印使用者資訊

void print(void) const

/*以下省略存款、取款等功能

*/private:

//不允許拷貝帳號,拷貝建構函式私有化

account(account& that) {};

static double s_rate; //利率

static size_t s_size; //帳號個數

int m_id; //卡號

string m_name; //使用者名稱

int m_passwd; //密碼

double m_balance; //存款

};//以下靜態成員變數必須在類外定義、初始化

double account::s_rate = 0.003; //利率初始化

size_t account::s_size = 0; //帳號個數初始化

int main(void)

執行結果:

由此可見,類account中的靜態成員變數s_rate和s_size是共享與每個物件之中,且不依賴與物件而存在。

單例模式

當我們設計乙個類的時候,只允許存在唯一的物件例項的時候,就需要用到單例模式,單例模式一般分別有餓漢模式和懶漢模式。如**的計數器、資料庫應用的連線池、多執行緒應用的執行緒池等等都用到了單例模式。雖然可以通過定義乙個全域性變數(物件)貌似也可以實現,功能也差不多,但是全句變數(物件)的定義不受控制,防君子不防小人。

什麼是單例模式

單例模式只允許存在乙個物件,且在類外部是禁止建立例項的,所以建構函式必須都私有化。

在類的定義中,宣告乙個該類的靜態成員變數,這個變數是類唯一的例項,由該類自己維護。

在一般情況下,為了體現出類良好的封裝性,一般把這個靜態成員變數私有化,然後提供乙個靜態成員函式,通過該靜態成員函式可以訪問到該唯一的例項

餓漢模式

優點:該模式中,單例物件在程式執行前就存在,所以不需要考慮會被多個執行緒在某種情況下、同一時刻中建立多個物件。

缺點:該單例模式中的唯一物件無論是否被使用,都會被建立,降低空間利用率。

/*

單例模式 - 餓漢模式

*/#include using namespace std;

class singleton

private:

/*不允許使用者建立和拷貝物件,建構函式私有化*/

singleton(int x = 100) : m_data(x) {}

singleton(singleton& sigleton) {}

static singleton s_instance;

int m_data;

};//靜態成員變數必須在類外定義、初始化

singleton singleton::s_instance(200);

int main(void)

執行結果:

3物件的位址都相同,證明了返回的是同乙個變數的引用。

懶漢模式

優點:用則建立,不用不建立,什麼時候用什麼時候建立

/*

單例模式 - 懶漢模式

*/#include using namespace std;

class singleton

pthread_mutex_unlock(&mutex);

} return *s_instance;

}private:

singleton(int data = 100) : m_data(data) {}

singleton(singleton const&) {}

static singleton* s_instance;

int m_data;

};//初始化singleton中的靜態成員s_instance

singleton* singleton::s_instance = null;

int main(void)

使用靜態成員函式需要注意的地方:由於靜態成員不依賴於任何物件、且屬於類不屬於物件,所以靜態成員函式只能訪問靜態成員變數或呼叫靜態成員函式。

非靜態成員函式由於引數中隱藏著this指標,所以既可以訪問靜態成員變數或呼叫靜態成員函式,也可以訪問非靜態成員變數或呼叫非靜態成員函式。

OC成員變數 單例模式

main.m 單例模式 created by goddog on 15 1 2.1.乙個類始終只能建立乙個例項,則這個類被稱之為單例類 2.單例類可以通過static全域性變數來實現,程式考慮定義乙個static全域性變數,該變數用於儲存已建立的singleton物件,每次程式需要獲取該例項時,程式...

單例模式 餓漢模式(靜態常量)

餓漢模式 靜態常量 優缺點說明 1 優點 寫法比較簡單,就是在類裝載的時候就完成例項化。避免了執行緒同 步問題。2 缺點 在類裝載的時候就完成例項化,沒有達到lazy loading的效果。如果從始 至終從未使用過這個例項,則會造成記憶體的浪費 3 這種方式基於classloder機制避免了多執行緒...

單例模式 靜態內部類

靜態內部類是乙個很好的實現單例的方式 看 package cn.liz.syn public class staticinner 私有的靜態內部類 private static class inner 公共的 獲取例項的方法 public static staticinner getinstance...