C++簡(jiǎn)明圖解分析靜態(tài)成員與單例設(shè)計(jì)模式
靜態(tài)成員概述
1、靜態(tài)成員包括靜態(tài)成員數(shù)據(jù)、靜態(tài)成員函數(shù)
2、成員數(shù)據(jù)、成員函數(shù)被 static修飾 就叫靜態(tài)成員數(shù)據(jù)、靜態(tài)成員函數(shù)
3、不管這個(gè)類創(chuàng)建了多少個(gè)對(duì)象,靜態(tài)成員只有一份,這一份被所有屬于這個(gè)類的對(duì)象共享。
4、靜態(tài)成員 是屬于類 而不是具體的某個(gè)對(duì)象。
5、靜態(tài)成員 是在定義完類的時(shí)候 就存在了。
靜態(tài)成員數(shù)據(jù)
靜態(tài)變量,是在編譯階段就分配空間,對(duì)象還沒有創(chuàng)建時(shí),就已經(jīng)分配空間。
靜態(tài)成員變量必須在類中聲明,在類外定義。
靜態(tài)數(shù)據(jù)成員不屬于某個(gè)對(duì)象,在為對(duì)象分配空間中不包括靜態(tài)成員所占空間。
class Data { public: int num;//普通成員變量 static int data;//靜態(tài)成員變量(類內(nèi)聲明) }; //定義的時(shí)候 不需要加static int Data::data=100;//類外定義+初始化 void test01() { //data是靜態(tài)成員變量 是屬于類 可以通過類名稱::直接訪問 cout<<Data::data<<endl;//100 //賦值 Data::data = 200; cout<<Data::data<<endl;//200 //data靜態(tài)變量 是所有對(duì)象 共享的 可以通過對(duì)象名訪問 Data ob1; ob1.data = 300; cout<<Data::data<<endl;//300 Data ob2; cout<<ob2.data<<endl;//300 //普通成員變量 屬于對(duì)象的 只能通過對(duì)象名訪問 ob1.num = 100; cout<<"ob2.num = "<<ob2.num<<endl;//隨機(jī)值 //cout<<Data::num<<endl;//普通成員變量不能通過類名稱訪問 }
static修飾靜態(tài)成員函數(shù)
靜態(tài)成員函數(shù):只能訪問私有靜態(tài)數(shù)據(jù)
引出:
class Data { private: int num;//普通成員變量 static int data;//靜態(tài)成員變量(類內(nèi)聲明) public: //普通成員函數(shù) 依賴于 對(duì)象的 必須對(duì)象調(diào)用 int getData(void) { return data; } }; //定義的時(shí)候 不需要加static int Data::data=100;//類外定義+初始化 void test01() { //cout<<Data::data<<endl;//err 靜態(tài)data是私有的 類外不能直接訪問 //cout<< Data::getData()<<endl;//err getData() 必須對(duì)象調(diào)用 Data ob; cout<<ob.getData()<<endl; //存在問題:data靜態(tài)的 在創(chuàng)建對(duì)象之前 就已經(jīng)存在 //如果類沒有實(shí)例化對(duì)象 難道 就不能使用data了嗎? //解決上述問題 就要用到靜態(tài)成員函數(shù) }
靜態(tài)成員函數(shù):
class Data { private: int num;//普通成員變量 static int data;//靜態(tài)成員變量(類內(nèi)聲明) public: //普通成員函數(shù) 依賴于 對(duì)象的 必須對(duì)象調(diào)用 int getData(void) { return data; } //靜態(tài)成員函數(shù) 屬于類 而不屬于對(duì)象 static int getDataStatic(void) { return data; } }; //定義的時(shí)候 不需要加static int Data::data=100;//類外定義+初始化 void test01() { //cout<<Data::data<<endl;//err 靜態(tài)data是私有的 類外不能直接訪問 //cout<< Data::getData()<<endl;//err getData() 必須對(duì)象調(diào)用 Data ob; cout<<ob.getData()<<endl; //存在問題:data靜態(tài)的 在創(chuàng)建對(duì)象之前 就已經(jīng)存在 //如果類沒有實(shí)例化對(duì)象 難道 就不能使用data了嗎? //解決上述問題 就要用到靜態(tài)成員函數(shù) //1、靜態(tài)成員函數(shù) 屬于類 就可以通過類名稱直接訪問 cout<<Data::getDataStatic()<<endl; //2、也可以通過對(duì)象名訪問(對(duì)象共享靜態(tài)成員函數(shù)) cout<<ob.getDataStatic()<<endl; }
注意:
1、靜態(tài)成員函數(shù)的目的 操作靜態(tài)成員數(shù)據(jù)。
2、靜態(tài)成員函數(shù) 不能訪問 非靜態(tài)成員數(shù)據(jù)。(靜態(tài)成員函數(shù)內(nèi)部沒有this指針)
3、普通成員函數(shù) 可以操作 靜態(tài)成員數(shù)據(jù) 非靜態(tài)成員數(shù)據(jù)。
4、靜態(tài)成員變量 和 靜態(tài)成員函數(shù) 都有權(quán)限之分。
const修飾靜態(tài)成員
如果一個(gè)類的成員,既要實(shí)現(xiàn)共享,又要實(shí)現(xiàn)不可改變,那就用 static const 修飾
class Data { public: const static int data;//靜態(tài)成員變量(類內(nèi)聲明) public: //靜態(tài)成員函數(shù) 屬于類 而不屬于對(duì)象 static int getDataStatic(void) { //num = 200;//err 靜態(tài)成員函數(shù) 不能訪問普通成員變量 return data; } }; //定義的時(shí)候 不需要加static const int Data::data=100;//類外定義+初始化 void test02() { //訪問 cout<<Data::data<<endl; //賦值 //Data::data = 200;//err data靜態(tài)成員只讀 cout<<Data::data<<endl; }
const修飾對(duì)象 叫常對(duì)象
const int num = 10;//系統(tǒng)不會(huì)給num開辟空間 num被放入符號(hào)表中 如果后期對(duì)&num 這時(shí)系統(tǒng)才會(huì)給num開辟空間
class Data { private: int data; mutable int num; public: //遍歷 成員的函數(shù) 不會(huì)去修改成員的值 //如果函數(shù)不會(huì)更改成員數(shù)據(jù) 就讓編譯器知道 這是一個(gè)const函數(shù) void myPrintData(void) const { //data =10000;//err const修飾函數(shù) 函數(shù)不能操作普通成員變量 cout<<this->data<<endl; //cout<<data<<endl; //mutable修飾的成員變量 可以修改 num = 200; } //編譯器認(rèn)為 普通成員函數(shù) 存在修改成員變量 可能 void setData(int data) const { //this->data = data; return; } Data() { cout<<"無參構(gòu)造"<<endl; } Data(int data) { this->data =data; cout<<"有參構(gòu)造"<<endl; } Data(const Data &ob) { this->data = ob.data; cout<<"拷貝構(gòu)造"<<endl; } ~Data() { cout<<"析構(gòu)函數(shù)"<<endl; } }; void test03() { //常對(duì)象 const Data ob1(200); //常對(duì)象 只能調(diào)用const修飾的函數(shù) 遍歷成員數(shù)據(jù) ob1.setData(20000); ob1.myPrintData(); }
運(yùn)行結(jié)果:
const修飾成員函數(shù)
用const修飾的成員函數(shù)時(shí),const修飾this指針指向的內(nèi)存區(qū)域,成員函數(shù)體內(nèi)不可以修改本類中的任何普通成員變量, 當(dāng)成員變量類型符前用mutable修飾時(shí)例外。
int myFun(void) const //const修飾的是成員函數(shù) {}//函數(shù)內(nèi)部不能修改 普通成員變量 mutable修飾時(shí)例外
class Data2 { public: int a; mutable int b; public: Data2(int a, int b):a(a),b(b) { // this->a = a; // this->b = b; } //const修飾的是整個(gè)成員函數(shù) 表明在函數(shù)內(nèi)部只能對(duì)數(shù)據(jù)成員 讀操作 void showData2(void) const { //a=100;//err //如果在const修飾的成員函數(shù)中 修改成員數(shù)據(jù)的值 請(qǐng)事先對(duì)成員數(shù)據(jù)進(jìn)行mutable修飾 b = 200;//ok cout<<"a="<<a<<", b="<<b<<endl; } }; void test02() { Data2 ob(10,20); ob.showData2(); }
靜態(tài)成員案例
案例1:靜態(tài)成員 統(tǒng)計(jì)類 實(shí)例化對(duì)象的 個(gè)數(shù)
#include <iostream> using namespace std; class Data { public: Data() { cout<<"無參構(gòu)造"<<endl; count++; } Data(const Data &ob) { cout<<"拷貝構(gòu)造函數(shù)"<<endl; count++; } ~Data() { count--; cout<<"析構(gòu)函數(shù)"<<endl; } static int count; }; int Data::count = 0; int main(int argc, char *argv[]) { Data ob1; Data ob2; { Data ob3; Data ob4; cout<<"對(duì)象的個(gè)數(shù):"<<Data::count<<endl; } cout<<"對(duì)象的個(gè)數(shù):"<<Data::count<<endl; return 0; }
運(yùn)行結(jié)果:
單例模式
單例模式 所設(shè)計(jì)的類 只能實(shí)例化一個(gè)對(duì)象。
單例模式的步驟:
1、不允許Printer實(shí)例對(duì)象(把構(gòu)造、拷貝構(gòu)造函數(shù)私有化)
2、定義一個(gè)靜態(tài)對(duì)象指針 保存唯一的對(duì)象地址
3、定義一個(gè)靜態(tài) 成員函數(shù) 拿到唯一的對(duì)象的地址 方便外界使用
案例:
單例模式設(shè)計(jì)--打印機(jī)(重要)
步驟1:在單例類內(nèi)部定義了一個(gè)Singleton類型的靜態(tài)對(duì)象,作為外部共享的唯一實(shí)例
步驟2:提供一個(gè)公共靜態(tài)的方法,讓客戶可以訪問它的唯一實(shí)例。
步驟3:為了防止在外部對(duì)實(shí)例化其他對(duì)象,將其默認(rèn)構(gòu)造函數(shù)和拷貝構(gòu)造函數(shù)設(shè)計(jì)為私有
#include <iostream> using namespace std; class Printer { public: //2、提供一個(gè)方法 獲得單例指針 static Printer* getSignlePrint(void) { return signlePrint; } //4、設(shè)置功能函數(shù)(自定義) void printText(char *str) { cout<<"打印"<<str<<endl; count++; } int count; private: //1、定義一個(gè)靜態(tài)的 對(duì)象指針變量 保存唯一實(shí)例地址 static Printer *signlePrint; private: //3、防止 該類實(shí)例化其他對(duì)象 將構(gòu)造函數(shù)全部 私有 Printer(){count=0;} Printer(const Printer &ob){} }; Printer *Printer::signlePrint = new Printer; int main(int argc, char *argv[]) { //打印任務(wù)1 Printer *p1 = Printer::getSignlePrint(); p1->printText("入職報(bào)告1"); p1->printText("體檢報(bào)告2"); p1->printText("離職證明3"); //打印任務(wù)2 Printer *p2 = Printer::getSignlePrint(); p2->printText("入職報(bào)告1"); p2->printText("體檢報(bào)告2"); p2->printText("離職證明3"); cout<<"打印任務(wù)數(shù)量:"<<p2->count<<endl; return 0; }
運(yùn)行結(jié)果:
到此這篇關(guān)于C++簡(jiǎn)明圖解分析靜態(tài)成員與單例設(shè)計(jì)模式的文章就介紹到這了,更多相關(guān)C++靜態(tài)成員內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言三子棋游戲的簡(jiǎn)單設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言三子棋游戲的簡(jiǎn)單設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10直觀理解C語(yǔ)言中指向一位數(shù)組與二維數(shù)組的指針
這篇文章主要介紹了直觀理解C語(yǔ)言中指向一位數(shù)組與二維數(shù)組的指針,數(shù)組指針是C語(yǔ)言入門學(xué)習(xí)過程中的重點(diǎn)和難點(diǎn),需要的朋友可以參考下2016-05-05C++編程產(chǎn)生指定范圍內(nèi)的隨機(jī)數(shù)
這篇文章主要為大家詳細(xì)介紹了C++編程產(chǎn)生指定范圍內(nèi)的隨機(jī)數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09C語(yǔ)言實(shí)現(xiàn)經(jīng)典排序算法的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C語(yǔ)言實(shí)現(xiàn)經(jīng)典排序算法中的冒泡排序、選擇排序、插入排序、希爾排序,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-08-08C++實(shí)現(xiàn)循環(huán)隊(duì)列
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)循環(huán)隊(duì)列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-01-01