国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁(yè) > news >正文

重慶快建網(wǎng)站網(wǎng)絡(luò)推廣技術(shù)外包

重慶快建網(wǎng)站,網(wǎng)絡(luò)推廣技術(shù)外包,網(wǎng)站賣(mài)給做博彩的,四川省四川省住房和城鄉(xiāng)建設(shè)廳網(wǎng)站設(shè)計(jì)模式 如何解決復(fù)雜性? 分解 核心思想:分而治之,將大問(wèn)題分解為多個(gè)小問(wèn)題,將復(fù)雜問(wèn)題分解為多個(gè)簡(jiǎn)單的問(wèn)題。 抽象 核心思想:從高層次角度講,人們處理復(fù)雜性有一個(gè)通用的技術(shù),及抽象。…

設(shè)計(jì)模式

如何解決復(fù)雜性?

分解

核心思想:分而治之,將大問(wèn)題分解為多個(gè)小問(wèn)題,將復(fù)雜問(wèn)題分解為多個(gè)簡(jiǎn)單的問(wèn)題。

抽象

核心思想:從高層次角度講,人們處理復(fù)雜性有一個(gè)通用的技術(shù),及抽象。由于不能掌握全部的復(fù)雜對(duì)象,選擇護(hù)士他的非本質(zhì)細(xì)節(jié),而去處理泛化和理想化的對(duì)象模型。

總結(jié)來(lái)說(shuō)就是,復(fù)用最好的代碼就是復(fù)用性高。

面向?qū)ο笤O(shè)計(jì)原則

對(duì)象的概念

  • 從語(yǔ)言實(shí)現(xiàn)層面來(lái)看,對(duì)象封裝了代碼和數(shù)據(jù)。
  • 從規(guī)格層面講,對(duì)象是一系列可被使用的公共接口。
  • 從概念層面講,對(duì)象時(shí)某種擁有責(zé)任的抽象。

設(shè)計(jì)原則

依賴(lài)倒置原則(DIP):

  • 高層模塊(穩(wěn)定)不應(yīng)該依賴(lài)于低層模塊(變化)二者都應(yīng)該依賴(lài)于抽象(穩(wěn)定)。
  • 抽象(穩(wěn)定)不應(yīng)該依賴(lài)于實(shí)現(xiàn)細(xì)節(jié)(變化),實(shí)現(xiàn)細(xì)節(jié)應(yīng)該依賴(lài)于抽象(穩(wěn)定)。

開(kāi)放封閉原則(OCP):

  • 對(duì)擴(kuò)展開(kāi)放,對(duì)更改封閉。
  • 類(lèi)模塊應(yīng)該是可擴(kuò)展的,但是不可修改。

單一職責(zé)原則(SRP):

  • 一個(gè)類(lèi)應(yīng)該僅有一個(gè)引起它變化的原則。
  • 變化的方向隱含著類(lèi)的責(zé)任。

Liskov替換原則(LSP):

  • 子類(lèi)必須能夠替換他們的基類(lèi)。
  • 繼承表達(dá)類(lèi)型抽象

接口隔離原則(ISP):

  • 不應(yīng)該強(qiáng)迫客戶(hù)程序依賴(lài)他們不用的方法。
  • 接口應(yīng)該小而完備。

優(yōu)先使用對(duì)象組合,而不是類(lèi)繼承

  • 類(lèi)繼承通常為“白箱復(fù)用”,對(duì)象組合通常為“黑箱復(fù)用”。
  • 繼承在某種程度上破壞了封裝性,子類(lèi)父類(lèi)耦合度很高。
  • 而對(duì)象組合則只要求被組合的對(duì)象具有良好定義的接口,耦合度低。

封裝變化點(diǎn)

  • 使用封裝來(lái)創(chuàng)建對(duì)象之間的分界層,讓設(shè)計(jì)者可以在分界層的一側(cè)進(jìn)行修改,而不會(huì)對(duì)另一側(cè)產(chǎn)生不良影響,從而實(shí)現(xiàn)層次間的松耦合。

針對(duì)接口與編碼,而不是針對(duì)實(shí)現(xiàn)編程產(chǎn)業(yè)強(qiáng)盛的標(biāo)志

  • 不將變量類(lèi)型聲明為某個(gè)特定的具體類(lèi),而是聲明為某個(gè)接口
  • 客戶(hù)程序無(wú)需獲知對(duì)象的具優(yōu)類(lèi)型,只需要知道對(duì)象所具有的接口。
  • 減少系統(tǒng)中各部分的依賴(lài)關(guān)系從而實(shí)現(xiàn)“高內(nèi)聚、松耦合’的類(lèi)型設(shè)計(jì)方案。

GOF-23模式分類(lèi)

目的來(lái)看:

  • 創(chuàng)建型模式:將對(duì)象的部分創(chuàng)建工作延遲到子類(lèi)或者其他對(duì)象,從而應(yīng)對(duì)需求變化為對(duì)象創(chuàng)建時(shí)具體類(lèi)型實(shí)現(xiàn)引來(lái)的沖擊。
  • 結(jié)構(gòu)型模式:通過(guò)類(lèi)繼承或者對(duì)象組合獲得更靈活的結(jié)構(gòu),從而應(yīng)對(duì)需求變化為對(duì)象的結(jié)構(gòu)帶來(lái)的沖擊。
  • 行為型模式:通過(guò)類(lèi)繼承或者對(duì)象組合來(lái)劃分類(lèi)與對(duì)象間的職責(zé),從而應(yīng)對(duì)需求變化為多個(gè)交互的對(duì)象帶來(lái)的沖擊。

范圍來(lái)看:

  • 類(lèi)模式處理類(lèi)與子類(lèi)的靜態(tài)關(guān)系。
  • 對(duì)象模式處理對(duì)象間的動(dòng)態(tài)關(guān)系。

C++設(shè)計(jì)模式

工廠模式

工廠模式:主要是封裝了對(duì)象的創(chuàng)建。

簡(jiǎn)單工廠(Simple Factory)

優(yōu)點(diǎn):

  1. 把對(duì)象的創(chuàng)建封裝在一個(gè)接口函數(shù)里面,通過(guò)傳入不同的標(biāo)識(shí),返回創(chuàng)建的對(duì)象。
  2. 使用者不需要自己負(fù)責(zé)new對(duì)象,不用了解對(duì)象創(chuàng)建的詳細(xì)過(guò)程。

缺點(diǎn):

  1. 提供創(chuàng)建對(duì)象實(shí)例的接口函數(shù)不閉合,不能對(duì)修改關(guān)閉。

工廠方法(Factory Method)

優(yōu)點(diǎn):

  1. 使用Factory基類(lèi),提供一個(gè)純虛函數(shù)(創(chuàng)建產(chǎn)品),定義派生類(lèi)(具體產(chǎn)品的工廠)負(fù)責(zé)創(chuàng)建對(duì)應(yīng)的產(chǎn)品,可以做到不同的產(chǎn)品在不同的工廠進(jìn)行創(chuàng)建。能對(duì)現(xiàn)有工廠以及產(chǎn)品的修改關(guān)閉

缺點(diǎn):

  1. 忽略了產(chǎn)品之間的關(guān)聯(lián)關(guān)系,屬于一個(gè)產(chǎn)品簇的不應(yīng)該放到不同的工廠里面去創(chuàng)建。不符合產(chǎn)品對(duì)象創(chuàng)建邏輯;
  2. 工廠類(lèi)太多,難以維護(hù)。

抽象工廠(Abstact Factory)

優(yōu)點(diǎn):

  1. 把現(xiàn)有關(guān)聯(lián)關(guān)系、屬于同一個(gè)產(chǎn)品簇的所有產(chǎn)品創(chuàng)建的接口函數(shù)放在一個(gè)抽象工廠里面,派生類(lèi)(具體產(chǎn)品的工廠)應(yīng)該負(fù)責(zé)創(chuàng)建該產(chǎn)品簇里面的所有產(chǎn)品。

這里使用了一個(gè)汽車(chē)生產(chǎn)的工廠示例,列舉了簡(jiǎn)單工廠和工廠方法,并使用智能指針進(jìn)行對(duì)象空間優(yōu)化回收。

簡(jiǎn)單工廠和工廠方法

#include <iostream>
#include <string>
#include<memory>using namespace std;class Car
{
public:Car(string name):_name(name){}virtual void show() = 0; //定義純虛函數(shù),子類(lèi)必須實(shí)現(xiàn)protected:string _name;private:
};
class BMW:public Car
{
public:// 使用Car(name)類(lèi)似于_name(name),還是用了Car的_name,// 子類(lèi)繼承父類(lèi)的構(gòu)造函數(shù)可以參考 https://blog.csdn.net/aquapisces/article/details/104371658BMW(string name) : Car(name){};void show(){cout << "獲取了一輛寶馬汽車(chē)" << _name << endl;} 
protected : 
private:
};
class Audi : public Car
{
public:// 使用Car(name)類(lèi)似于_name(name),還是用了Car的_name,// 子類(lèi)繼承父類(lèi)的構(gòu)造函數(shù)可以參考 https://blog.csdn.net/aquapisces/article/details/104371658Audi(string name) : Car(name){};void show(){cout << "獲取了一輛奧迪汽車(chē)" << _name << endl;}protected:
private:
};// ------------------------------------------------------------------------------------------
/*
簡(jiǎn)單工廠存在以下問(wèn)題:開(kāi)閉原則,新增一個(gè)汽車(chē)則需要修改很多代碼;BMW類(lèi)和Audi類(lèi)都在一個(gè)工廠里面生產(chǎn)
*/
enum CarType
{bmw,audi
};
class SimpleFactory
{
public:Car* createCar(CarType ct){switch (ct){case bmw:return new BMW("X1");case audi:return new Audi("A6");default:cout << "傳入工廠的參數(shù)不正確:" << ct << endl;break;}return nullptr;}
};
// ------------------------------------------------------------------------------------------
/*
工廠方法
*/
class Factory
{
public:virtual Car* createCar(string name) = 0;
};
class BMWFactory:public Factory
{
public:Car* createCar(string name){return new BMW(name);}
};
class AudiFactory : public Factory
{
public:Car *createCar(string name){return new Audi(name);}
};
// ------------------------------------------------------------------------------------------int main()
{// unique_ptr無(wú)法進(jìn)行普通拷貝構(gòu)造和賦值unique_ptr<Car> p1=new BMW("X1");是錯(cuò)誤的// 最原始的對(duì)象產(chǎn)生unique_ptr<Car> p1(new BMW("X1"));unique_ptr<Car> p2(new Audi("A6"));// 簡(jiǎn)單工廠// unique_ptr<SimpleFactory> factory(new SimpleFactory());// unique_ptr<Car> p1(factory->createCar(bmw));// unique_ptr<Car> p2(factory->createCar(audi));// 工廠方法// unique_ptr<Factory> bmwFactory(new BMWFactory);// unique_ptr<Factory> audiFactory(new AudiFactory);// unique_ptr<Car> p1(bmwFactory->createCar("X6"));// unique_ptr<Car> p2(audiFactory->createCar("A8"));p1->show();p2->show();return 0;
}

抽象工廠方法

上一節(jié)中的工廠方法會(huì)存在一個(gè)問(wèn)題,在定義了一個(gè)Factory抽象類(lèi)后,每一個(gè)類(lèi)將對(duì)應(yīng)一個(gè)類(lèi)的工廠,如BWM->BMWFactoryAudi->AudiFactory,這樣會(huì)導(dǎo)致一個(gè)問(wèn)題,在生產(chǎn)一類(lèi)產(chǎn)品時(shí),如手機(jī)充電器和充電線,那么就又需要兩個(gè)工廠來(lái)實(shí)現(xiàn),所以這樣就會(huì)導(dǎo)致工廠冗余。所以,提出了抽象工廠來(lái)解決這個(gè)問(wèn)題,這里以汽車(chē)的生產(chǎn)部件為例進(jìn)行說(shuō)明:

#include <iostream>
#include <string>
#include<memory>using namespace std;class Car
{
public:Car(string name):_name(name){}virtual void show() = 0; //定義純虛函數(shù),子類(lèi)必須實(shí)現(xiàn)protected:string _name;private:
};
class BMW:public Car
{
public:// 使用Car(name)類(lèi)似于_name(name),還是用了Car的_name,// 子類(lèi)繼承父類(lèi)的構(gòu)造函數(shù)可以參考 https://blog.csdn.net/aquapisces/article/details/104371658BMW(string name) : Car(name){};void show(){cout << "獲取了一輛寶馬汽車(chē)" << _name << endl;} 
protected : 
private:
};
class Audi : public Car
{
public:// 使用Car(name)類(lèi)似于_name(name),還是用了Car的_name,// 子類(lèi)繼承父類(lèi)的構(gòu)造函數(shù)可以參考 https://blog.csdn.net/aquapisces/article/details/104371658Audi(string name) : Car(name){};void show(){cout << "獲取了一輛奧迪汽車(chē)" << _name << endl;}protected:
private:
};class Light
{
public:virtual void show() = 0;
};class BMWLight:public Light
{
public:void show(){cout << "BMW light!" << endl;}
};class AudiLight : public Light
{
public:void show(){cout << "Audi light!" << endl;}
};
/*
抽象工廠,對(duì)一組關(guān)聯(lián)關(guān)系的產(chǎn)品簇提供產(chǎn)品對(duì)象的統(tǒng)一創(chuàng)建。
有點(diǎn)類(lèi)似于工廠方法
*/
class AbstractFactory
{
public:virtual Car *createCar(string name) = 0;virtual Light *createCarLight() = 0;
};
class BMWFactory : public AbstractFactory
{
public:Car *createCar(string name){return new BMW(name);}Light *createCarLight(){return new BMWLight();}
};
class AudiFactory : public AbstractFactory
{
public:Car *createCar(string name){return new Audi(name);}Light *createCarLight(){return new AudiLight();}
};int main()
{// 抽象工廠方法unique_ptr<AbstractFactory> bmwFactory(new BMWFactory);unique_ptr<AbstractFactory> audiFactory(new AudiFactory);unique_ptr<Car> p1(bmwFactory->createCar("X6"));unique_ptr<Car> p2(audiFactory->createCar("A8"));unique_ptr<Light> l1(bmwFactory->createCarLight());unique_ptr<Light> l2(audiFactory->createCarLight());p1->show();p2->show();l1->show();l2->show();return 0;
}

代理模式

代理(proxy)模式:通過(guò)代理類(lèi),來(lái)控制實(shí)際對(duì)象的訪問(wèn)權(quán)限。其實(shí)也就是定義一個(gè)虛基類(lèi),子類(lèi)繼承虛基類(lèi)實(shí)現(xiàn)不同級(jí)別對(duì)象的實(shí)現(xiàn),可以看以下類(lèi)似代碼:

#include <iostream>
#include <string>
#include<memory>using namespace std;class VideoSite
{
public:virtual void freeMovie() = 0;virtual void vipMovie() = 0;virtual void ticketMovie() = 0;
};
class FixBugVideoSite:public VideoSite
{// 不同的用戶(hù)的訪問(wèn)權(quán)限可能不夠,所以下面三個(gè)函數(shù)有些對(duì)象不能調(diào)用void freeMovie(){cout << "觀看免費(fèi)電影" << endl;}void vipMovie(){cout << "觀看vip電影" << endl;}void ticketMovie(){cout << "觀看電影券電影" << endl;}
};// 代理類(lèi),用于代理FixBugVideoSite
class FreeVideoSiteProxy:public VideoSite
{
public:FreeVideoSiteProxy(){pVideo = new FixBugVideoSite();}~FreeVideoSiteProxy(){if(pVideo!=nullptr){delete pVideo;}pVideo = nullptr;}void freeMovie(){pVideo->freeMovie();}void vipMovie(){cout << "您目前只是普通用戶(hù),需要升級(jí)成vip才能觀看vip電影" << endl;}void ticketMovie(){cout << "您目前只是普通用戶(hù),需要購(gòu)買(mǎi)電影券才能觀看電影" << endl;}private:VideoSite *pVideo;
};
class VipVideoSiteProxy : public VideoSite
{
public:VipVideoSiteProxy(){pVideo = new FixBugVideoSite();}~VipVideoSiteProxy(){if (pVideo != nullptr){delete pVideo;}pVideo = nullptr;}void freeMovie(){pVideo->freeMovie();}void vipMovie(){pVideo->vipMovie();}void ticketMovie(){cout << "您目前只是普通用戶(hù),需要購(gòu)買(mǎi)電影券才能觀看電影" << endl;}private:VideoSite *pVideo;
};
int main()
{// unique_ptr<VideoSite> p1(new FreeVideoSiteProxy());unique_ptr<VideoSite> p1(new VipVideoSiteProxy());p1->freeMovie();p1->vipMovie();p1->ticketMovie();return 0;
}

觀察者模式

行為型模式:主要關(guān)注的是對(duì)象之間的通信。

以觀察者-監(jiān)聽(tīng)者模式(發(fā)布-訂閱模式)設(shè)計(jì)模式:主要關(guān)注的是對(duì)象的一對(duì)多的關(guān)系,也就是多個(gè)對(duì)象都依賴(lài)一個(gè)對(duì)象,當(dāng)該對(duì)象的狀態(tài)發(fā)生改變時(shí),其他對(duì)象都能夠結(jié)束到相應(yīng)的通知。

ps:一組數(shù)據(jù)改變(數(shù)據(jù)對(duì)象)->通過(guò)這一組數(shù)據(jù)->曲線圖(對(duì)象1)/柱狀圖(對(duì)象2)/圓餅圖(對(duì)象3)。當(dāng)數(shù)據(jù)對(duì)象改變時(shí),對(duì)象1、對(duì)象2、對(duì)象3應(yīng)該及時(shí)的收到相應(yīng)的通知。

#include <iostream>
#include <string>
#include<list>
#include<unordered_map>using namespace std;
/**
觀察者模式/訂閱模式:當(dāng)一個(gè)對(duì)象發(fā)生改變時(shí),會(huì)通知其他對(duì)象去處理對(duì)象的事件。
*/
class Observer
{
public:virtual void handle(int msgid) = 0;
};
class Observer1:public Observer
{void handle(int msgid){switch (msgid){case 1:cout << "observer1 recv 1 msg." << endl;break;case 2:cout << "observer1 recv 2 msg." << endl;break;default:cout << "observer1 recv unknow msg." << endl;break;}}
};
class Observer2 : public Observer
{void handle(int msgid){switch (msgid){case 3:cout << "observer2 recv 3 msg." << endl;break;case 2:cout << "observer2 recv 2 msg." << endl;break;default:cout << "observer2 recv unknow msg." << endl;break;}}
};
class Observer3 : public Observer
{void handle(int msgid){switch (msgid){case 1:cout << "observer3 recv 1 msg." << endl;break;case 3:cout << "observer3 recv 3 msg." << endl;break;default:cout << "observer3 recv unknow msg." << endl;break;}}
};
class Subjects
{
public:// 給主題添加觀察者對(duì)象void addObserver(Observer* obser,int msgid){// 和下面的操作一致,如果存在msgid為key的情況就直接插入,沒(méi)有就創(chuàng)建一個(gè)并插入_submap[msgid].push_back(obser);/**// 查找map中是否存在有key為msgid的值auto it = _submap.find(msgid);if(it != _submap.end()){it->second.push_back(obser);}else{list<Observer *> olist;olist.push_back(obser);_submap.insert(make_pair(msgid, olist));}*/}// 主題檢測(cè)發(fā)生改變,通知相應(yīng)的觀察者對(duì)象處理事件void dispatch(int msg){auto it = _submap.find(msg);if (it != _submap.end()){for(Observer* pObser:it->second){pObser->handle(msg);}}}
private:unordered_map<int, list<Observer *>> _submap;
};
int main()
{Subjects sub;Observer *p1 = new Observer1();Observer *p2 = new Observer2();Observer *p3 = new Observer3();sub.addObserver(p1, 1);sub.addObserver(p2, 3);sub.addObserver(p3, 1);sub.addObserver(p3, 2);sub.addObserver(p1, 3);sub.dispatch(2);return 0;
}

適配器模式

適配器模式:讓不兼容的接口可以在一起工作。

下方使用C++實(shí)現(xiàn)了一個(gè)電腦播放投影視頻的例子,電腦僅僅支持VGA接口,如何實(shí)現(xiàn)HDMI接口轉(zhuǎn)化成VGA來(lái)適配電腦使用。也就是如何實(shí)現(xiàn)一個(gè)VGA和HEMI類(lèi)的轉(zhuǎn)化接口。

#include <iostream>
#include <string>using namespace std;class VGA
{
public:virtual void play() = 0;
};
class TV01:public VGA
{
public:void play() { cout << "通過(guò)VGA接口連接投影儀,進(jìn)行視頻播放!" << endl; }
};class HDMI
{
public:virtual void play() = 0;
};
class TV02 : public HDMI
{
public:void play() { cout << "通過(guò)HDMI接口連接投影儀,進(jìn)行視頻播放!" << endl; }
};// 一定要繼承原來(lái)的類(lèi)
class VGA2HDMIAdapter:public VGA
{
public:VGA2HDMIAdapter(HDMI* p):phdmi(p){}void play() { phdmi->play(); }private:HDMI *phdmi;
};
class Computer
{
public:// 由于電腦只支持VGA接口,所以該方法的參數(shù)也只支持VGA接口的指針/引用void playVideo(VGA *pVGA) { pVGA->play(); }
};int main()
{// HDMI和VGA無(wú)法進(jìn)行互相轉(zhuǎn)化,電腦如何使用HDMI的play方法?/*1、換一個(gè)支持HDMI的電腦,也就是對(duì)Computer類(lèi)進(jìn)行重構(gòu),叫做代碼重構(gòu)。2、使用一個(gè)適配器(轉(zhuǎn)化頭),把VGA類(lèi)轉(zhuǎn)化為HDMI類(lèi),叫做添加適配器類(lèi)。*/Computer computer;computer.playVideo(new TV01());computer.playVideo(new VGA2HDMIAdapter(new TV02()));return 0;
}

裝飾器模式

裝飾器(decorate)模式和代理模式類(lèi)似。代理模式也就是定義委托類(lèi)和代理類(lèi)繼承抽象類(lèi),并重寫(xiě)函數(shù)方法,通過(guò)在代理類(lèi)中使用委托類(lèi)的對(duì)象調(diào)用不同級(jí)別代理的方法訪問(wèn)。

裝飾器主要是增加現(xiàn)有類(lèi)的功能,但是添加現(xiàn)有類(lèi)的一個(gè)方法還有一個(gè)方法,就是新建一個(gè)子類(lèi)。如果每次新建一個(gè)功能都需要新建一個(gè)子類(lèi)的話,那么代碼中就會(huì)有很多的子類(lèi)被添加進(jìn)來(lái)。

以下實(shí)現(xiàn)了一個(gè)汽車(chē)裝飾類(lèi)的代碼實(shí)現(xiàn):

#include <iostream>
#include <string>using namespace std;class Car
{
public:virtual void show() = 0;
};
class BMW : public Car
{
public:void show() { cout << "這是一輛寶馬汽車(chē)!有基本配置"; }
};
class Audi : public Car
{
public:void show() { cout << "這是一輛奧迪汽車(chē)!有基本配置"; }
};
class Benc : public Car
{
public:void show() { cout << "這是一輛奔馳汽車(chē)!有基本配置"; }
};
// 裝飾器
class CarDecorator01 : public Car
{
public:CarDecorator01(Car *p) : pCar(p){};void show(){pCar->show();cout << ",輔助駕駛";}
private: Car *pCar;
};
class CarDecorator02 : public Car
{
public:CarDecorator02(Car *p) : pCar(p){};void show(){pCar->show();cout << ",自動(dòng)校正";}private:Car *pCar;
};
class CarDecorator03 : public Car
{
public:CarDecorator03(Car *p) : pCar(p){};void show(){pCar->show();cout << ",車(chē)道偏離";}private:Car *pCar;
};
int main()
{Car *p1 = new CarDecorator01(new BMW());p1 = new CarDecorator02(p1);p1->show();cout << endl;Car *p2 = new CarDecorator02(new Audi());p2->show();cout << endl;Car *p3 = new CarDecorator03(new Benc());p3->show();cout << endl;return 0;
}

單例模式

常見(jiàn)的類(lèi)創(chuàng)建一個(gè)對(duì)象,便會(huì)得到一個(gè)新的對(duì)象。而單例模式則有些不同。

單例模式:一個(gè)類(lèi)不管創(chuàng)建多少次對(duì)象,永遠(yuǎn)只能得到該類(lèi)型一個(gè)對(duì)象的實(shí)例??梢圆榭碈++實(shí)現(xiàn)MySQL數(shù)據(jù)庫(kù)連接池中的線程池獲取代碼,將線程池定義為靜態(tài)成員方法和靜態(tài)成員變量,導(dǎo)致其處于靜態(tài)變量區(qū),只需要初始化一次。類(lèi)似的日志模塊應(yīng)該也可以使用單例模式。

餓漢式單例模式:還沒(méi)有獲取實(shí)例對(duì)象,實(shí)例對(duì)象就已經(jīng)產(chǎn)生了。
懶漢式單例模式:唯一的實(shí)例對(duì)象,直到第一次獲取它的時(shí)候才產(chǎn)生。

下面介紹了兩種單例模式的代碼設(shè)計(jì),其中提供了兩種懶漢式單例模式的示例:

#include <iostream>
#include <string>
#include<mutex>
using namespace std;// 餓漢式單例模式,線程安全的
class HungrySingleton
{
public:// 因?yàn)槠洳荒芤蕾?lài)對(duì)象,所以要定義成靜態(tài)成員方法,獲取類(lèi)的唯一實(shí)例對(duì)象的方法static HungrySingleton* getSingleton(){return &instance;}
private:// 單例模式,不允許用戶(hù)new對(duì)象,所以需要使用構(gòu)造函數(shù)私有化HungrySingleton(){}static HungrySingleton instance;// 將拷貝構(gòu)造函數(shù)和賦值操作符重載進(jìn)行刪除,使其不能完成對(duì)象創(chuàng)建,只能依賴(lài)getSingleton過(guò)去唯一的實(shí)例化對(duì)象HungrySingleton& operator=(const HungrySingleton &) = delete;HungrySingleton(const HungrySingleton &) = delete;
};
// 類(lèi)內(nèi)定義,類(lèi)外初始化,更多static初始化查看 https://blog.csdn.net/sevenjoin/article/details/81772792
// 靜態(tài)成員在數(shù)據(jù)段,在main函數(shù)之前就創(chuàng)建了,如果不使用的話,這個(gè)資源就浪費(fèi)了
HungrySingleton HungrySingleton::instance;mutex lazySingletonMtx;// 懶漢式單例模式,線程安全的
class LazySingleton
{
public:// 因?yàn)槠洳荒芤蕾?lài)對(duì)象,所以要定義成靜態(tài)成員方法,獲取類(lèi)的唯一實(shí)例對(duì)象的方法// 可重入函數(shù)的概念?一個(gè)線程還沒(méi)執(zhí)行完,該函數(shù)不能被另一個(gè)線程執(zhí)行,也就是線程互斥static LazySingleton *getSingleton(){   if(instance==nullptr){lock_guard<mutex> lck(lazySingletonMtx); // 所以多線程環(huán)境下需要加鎖和雙重判斷/*不是線程安全,下面這個(gè)instance = new LazySingleton()需要執(zhí)行-:開(kāi)辟內(nèi)存、構(gòu)造對(duì)象、instance賦值*/if(instance==nullptr){ // 雙重判斷,防止兩個(gè)線程同時(shí)進(jìn)入上層的if判斷中instance = new LazySingleton();}}return instance;}private:// 單例模式,不允許用戶(hù)new對(duì)象,所以需要使用構(gòu)造函數(shù)私有化LazySingleton(){}static LazySingleton*volatile instance;// 將拷貝構(gòu)造函數(shù)和賦值操作符重載進(jìn)行刪除,使其不能完成對(duì)象創(chuàng)建,只能依賴(lài)getSingleton過(guò)去唯一的實(shí)例化對(duì)象LazySingleton &operator=(const LazySingleton &) = delete;LazySingleton(const LazySingleton &) = delete;
};
// 類(lèi)內(nèi)定義,類(lèi)外初始化,更多static初始化查看 https://blog.csdn.net/sevenjoin/article/details/81772792
// 靜態(tài)成員在數(shù)據(jù)段,在main函數(shù)之前就創(chuàng)建了,如果不使用的話,這個(gè)資源就浪費(fèi)了
LazySingleton*volatile LazySingleton::instance=nullptr;// 懶漢式單例模式,線程安全的
class LazySingleton2
{
public:// 因?yàn)槠洳荒芤蕾?lài)對(duì)象,所以要定義成靜態(tài)成員方法,獲取類(lèi)的唯一實(shí)例對(duì)象的方法// 可重入函數(shù)的概念?一個(gè)線程還沒(méi)執(zhí)行完,該函數(shù)不能被另一個(gè)線程執(zhí)行,也就是線程互斥static LazySingleton2 *getSingleton(){// 靜態(tài)對(duì)象,運(yùn)行到這個(gè)函數(shù)才開(kāi)始初始化// 函數(shù)靜態(tài)局部變量的初始化,在匯編指令上已經(jīng)自動(dòng)添加線程互斥指令static LazySingleton2 instance;return &instance;}private:// 單例模式,不允許用戶(hù)new對(duì)象,所以需要使用構(gòu)造函數(shù)私有化LazySingleton2(){}// 將拷貝構(gòu)造函數(shù)和賦值操作符重載進(jìn)行刪除,使其不能完成對(duì)象創(chuàng)建,只能依賴(lài)getSingleton過(guò)去唯一的實(shí)例化對(duì)象LazySingleton2 &operator=(const LazySingleton2 &) = delete;LazySingleton2(const LazySingleton2 &) = delete;
};int main()
{HungrySingleton *p1 = HungrySingleton::getSingleton();HungrySingleton *p2 = HungrySingleton::getSingleton();HungrySingleton *p3 = HungrySingleton::getSingleton();cout << p1 << " " << p2 << " " << p3 << endl; // 0x407030 0x407030 0x407030LazySingleton *p4 = LazySingleton::getSingleton();LazySingleton *p5 = LazySingleton::getSingleton();LazySingleton *p6 = LazySingleton::getSingleton();cout << p4 << " " << p5 << " " << p6 << endl; // 0x25d2430 0x25d2430 0x25d2430// HungrySingleton t = *p1; // 拷貝構(gòu)造函數(shù)私有化之后就不能完成拷貝構(gòu)造了return 0;
}

一般情況下第二種懶漢式單例模式用的比較多,也更簡(jiǎn)單,在靜態(tài)成員方法中定義靜態(tài)成員對(duì)象。

http://aloenet.com.cn/news/37196.html

相關(guān)文章:

  • 網(wǎng)站算信息化建設(shè)電腦版百度網(wǎng)盤(pán)
  • 成都網(wǎng)站建設(shè)公司常熟網(wǎng)站建設(shè)
  • 做鞋的垂直網(wǎng)站百度客服24小時(shí)電話人工服務(wù)
  • b2c購(gòu)物網(wǎng)站開(kāi)發(fā)西安seo網(wǎng)站關(guān)鍵詞優(yōu)化
  • 做旅行網(wǎng)站的意義百度官網(wǎng)app下載安裝
  • 哪些網(wǎng)站可以做邀請(qǐng)函精準(zhǔn)大數(shù)據(jù)獲客系統(tǒng)
  • 免費(fèi)行情的軟件入口下載路由器優(yōu)化大師
  • 宣城市建設(shè)銀行網(wǎng)站建站流程
  • 外貿(mào)網(wǎng)站建設(shè)步驟網(wǎng)站設(shè)計(jì)公司多少錢(qián)
  • 青島中小企業(yè)網(wǎng)站制作公司網(wǎng)站建設(shè)費(fèi)用多少
  • 百度制作的wordpress工具欄seo在線工具
  • 個(gè)人做網(wǎng)站的流程淘寶推廣
  • 找人做公司網(wǎng)站百度商城
  • 網(wǎng)站建設(shè)項(xiàng)目采購(gòu)公告天津seo優(yōu)化公司
  • 怎么做接口網(wǎng)站企業(yè)推廣方法
  • 在局網(wǎng)站 作風(fēng)建設(shè)免費(fèi)頂級(jí)域名注冊(cè)網(wǎng)站
  • 高端網(wǎng)站建設(shè)公司興田德潤(rùn)可以不上海網(wǎng)絡(luò)推廣排名公司
  • wordpress登陸頁(yè)面保護(hù)插件seo點(diǎn)擊工具
  • 建筑電工證查詢(xún)網(wǎng)站企業(yè)seo案例
  • 網(wǎng)站名和域名的區(qū)別seo推廣多少錢(qián)
  • 如何創(chuàng)建自己網(wǎng)站電商項(xiàng)目策劃書(shū)
  • 做阿里巴巴網(wǎng)站圖片大全如何做公司網(wǎng)站推廣
  • 做曖視頻網(wǎng)站大全什么平臺(tái)可以做引流推廣
  • 網(wǎng)站推廣的優(yōu)勢(shì)有哪些seo課程培訓(xùn)視頻
  • 怎么做網(wǎng)站前臺(tái)站長(zhǎng)之家怎么找網(wǎng)址
  • 免費(fèi)網(wǎng)站建設(shè)塔山雙喜泉州全網(wǎng)營(yíng)銷(xiāo)推廣
  • 門(mén)戶(hù)網(wǎng)站和社交網(wǎng)絡(luò)的區(qū)別百度平臺(tái)商家我的訂單查詢(xún)
  • 網(wǎng)站登錄賬號(hào)密碼保存在哪里推廣手段有哪些
  • 螞蟻幣是什么網(wǎng)站建設(shè)網(wǎng)站推廣應(yīng)該怎么做?
  • 長(zhǎng)沙優(yōu)化官網(wǎng)公司滁州網(wǎng)站seo