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語言中指向一位數(shù)組與二維數(shù)組的指針
這篇文章主要介紹了直觀理解C語言中指向一位數(shù)組與二維數(shù)組的指針,數(shù)組指針是C語言入門學(xué)習(xí)過程中的重點(diǎn)和難點(diǎn),需要的朋友可以參考下2016-05-05
C++編程產(chǎn)生指定范圍內(nèi)的隨機(jī)數(shù)
這篇文章主要為大家詳細(xì)介紹了C++編程產(chǎn)生指定范圍內(nèi)的隨機(jī)數(shù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
C語言實(shí)現(xiàn)經(jīng)典排序算法的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用C語言實(shí)現(xiàn)經(jīng)典排序算法中的冒泡排序、選擇排序、插入排序、希爾排序,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-08-08
C++實(shí)現(xiàn)循環(huán)隊(duì)列
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)循環(huán)隊(duì)列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-01-01

