C++享元模式詳解
未引入享元模式
#include <iostream>
#include <list>
#include <map>
using namespace std;
enum class EnumColor //棋子類型
{
Black, //黑
White //白
};
struct Position //棋子位置
{
int m_x;
int m_y;
Position(int tmpx, int tmpy) :m_x(tmpx), m_y(tmpy) {} //構(gòu)造函數(shù)
};
/*棋子類*/
class Piece
{
public:
//構(gòu)造函數(shù)
Piece(EnumColor tmpcolor, Position tmppos) :m_color(tmpcolor), m_pos(tmppos){}
//棋子的繪制
void draw()
{
if(m_color == EnumColor::Black)
{
cout << "在位置:(" << m_pos.m_x << "," << m_pos.m_y << ")處繪制了一個黑色棋子!" << endl;
}
else
{
cout << "在位置:(" << m_pos.m_x << "," << m_pos.m_y << ")處繪制了一個白色棋子!" << endl;
}
}
private:
EnumColor m_color; //棋子顏色
Position m_pos; //棋子位置
};
int main()
{
//檢測內(nèi)存泄漏
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
Piece* p_piece1 = new Piece(EnumColor::Black, Position(3, 3)); //黑色落子到3,3位置
p_piece1->draw();
Piece* p_piece2 = new Piece(EnumColor::White, Position(5, 5)); //白色落子到5,5位置
p_piece2->draw();
Piece* p_piece3 = new Piece(EnumColor::Black, Position(4, 6)); //黑色落子到4,6位置
p_piece3->draw();
Piece* p_piece4 = new Piece(EnumColor::White, Position(5, 7)); //白色落子到5,7位置
p_piece4->draw();
//釋放資源
delete p_piece1;
delete p_piece2;
delete p_piece3;
delete p_piece4;
return 0;
}

對于上面的例程來說,棋子的類型無非就是兩種,黑和白,在實(shí)際的下棋過程當(dāng)中,只有位置是不一樣的,但是卻衍生出了多個具有相似度的對象,我們能否進(jìn)行改造一下,比如,對象只有兩個,黑和白,在實(shí)際的運(yùn)轉(zhuǎn)的時(shí)候,改變他們的位置就可以了,這樣就不用new很多給相似的對象出來了。下面我們進(jìn)行改造一下。引入享元模式。
引入享元模式
#include <iostream>
#include <list>
#include <map>
using namespace std;
enum EnumColor //棋子類型
{
Black, //黑
White //白
};
struct Position //棋子位置
{
int m_x;
int m_y;
Position(int tmpx, int tmpy) :m_x(tmpx), m_y(tmpy) {} //構(gòu)造函數(shù)
};
class Piece //棋子抽象類
{
public:
virtual ~Piece() {}
public:
virtual void draw(Position tmppos) = 0;
};
class BlackPiece :public Piece //黑色棋子
{
public:
virtual void draw(Position tmppos)
{
cout << "在位置:(" << tmppos.m_x << "," << tmppos.m_y << ")處繪制了一個黑色棋子!" << endl;
}
};
class WhitePiece :public Piece //白色棋子
{
public:
virtual void draw(Position tmppos)
{
cout << "在位置:(" << tmppos.m_x << "," << tmppos.m_y << ")處繪制了一個白色棋子!" << endl;
}
};
class pieceFactory //創(chuàng)建棋子的工廠
{
public:
virtual ~pieceFactory()
{
//釋放內(nèi)存
for(auto iter = m_FlyWeightMap.begin(); iter != m_FlyWeightMap.end(); ++iter)
{
Piece* tmpfw = iter->second;
delete tmpfw;
}
m_FlyWeightMap.clear();
}
//獲取享元對象,也就是獲取被共享的棋子對象
Piece* getFlyWeight(EnumColor tmpcolor)
{
auto iter = m_FlyWeightMap.find(tmpcolor);
if(iter == m_FlyWeightMap.end())
{
//沒有該享元對象,那么就創(chuàng)建出來
Piece* tmpfw = nullptr;
if(tmpcolor == Black) //黑子
{
tmpfw = new BlackPiece();
}
else //白子
{
tmpfw = new WhitePiece();
}
//以棋子顏色枚舉值作為key,增加條目到map中
m_FlyWeightMap.insert(make_pair(tmpcolor, tmpfw));
return tmpfw;
}
else
{
return iter->second;
}
}
private:
std::map<EnumColor, Piece*> m_FlyWeightMap; //享元池,用map容器來保存所有的享元對象,一共就兩個享元對象(黑色棋子一個,白色棋子一個)
};
int main()
{
//檢測內(nèi)存泄漏
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
pieceFactory* pfactory = new pieceFactory();
Piece* p_piece1 = pfactory->getFlyWeight(Black);
p_piece1->draw(Position(3, 3)); //黑子落子到3,3位置
Piece* p_piece2 = pfactory->getFlyWeight(White);
p_piece2->draw(Position(5, 5)); //白子落子到5,5位置
Piece* p_piece3 = pfactory->getFlyWeight(Black);
p_piece3->draw(Position(4, 6)); //黑子落子到4,6位置
Piece* p_piece4 = pfactory->getFlyWeight(White);
p_piece4->draw(Position(5, 7)); //白子落子到5,7位置
//釋放資源
delete pfactory;
return 0;
}


總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
詳解使用Mybatis-plus + velocity模板生成自定義的代碼
這篇文章主要介紹了詳解使用Mybatis-plus + velocity模板生成自定義的代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
tomcat部署java web項(xiàng)目遇到的問題及解決方法
這篇文章主要介紹了tomcat部署java web項(xiàng)目遇到的問題及解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07
基于javaMybatis存進(jìn)時(shí)間戳的問題
這篇文章主要介紹了javaMybatis存進(jìn)時(shí)間戳的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06
Java實(shí)現(xiàn)升級版布谷鳥闖關(guān)游戲的示例代碼
升級版布谷鳥闖關(guān)游戲是一個基于java的布谷鳥闖關(guān)游戲,鼠標(biāo)左鍵點(diǎn)擊控制鳥的位置穿過管道間的縫隙。文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2022-02-02
Java中DateTimeFormatter的使用方法和案例
在Java中,DateTimeFormatter類用于格式化和解析日期時(shí)間對象,它是日期時(shí)間格式化的強(qiáng)大而靈活的工具,本文將和大家一起探討Java中DateTimeFormatter的使用方法和案例,需要的朋友可以參考下2023-10-10
MyBatis?@Select注解介紹:基本用法與動態(tài)SQL拼寫方式
這篇文章主要介紹了MyBatis?@Select注解介紹:基本用法與動態(tài)SQL拼寫方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07

