当前位置: 首页 > wzjs >正文

网站 建设意见牌具做网站

网站 建设意见,牌具做网站,长春网站设计公司,深圳做app网站的公司名称七、单件模式 单件(Singleton) 模式也称单例模式/单态模式,是一种创建型模式,用于创建只能产生 一个对象实例 的类。该模式比较特殊,其实现代码中没有用到设计模式中经常提起的抽象概念,而是使用了一种比较特殊的语法结构&#x…

七、单件模式

单件(Singleton) 模式也称单例模式/单态模式,是一种创建型模式,用于创建只能产生 一个对象实例 的类。该模式比较特殊,其实现代码中没有用到设计模式中经常提起的抽象概念,而是使用了一种比较特殊的语法结构(私有的构造函数)实现类的定义。
该模式比较好理解,也比较常用,但要设计得好并不容易,有许多细节需要把握,本章将详细探讨。

7.1 单件类的基本概念和实现

在一个软件中,往往存在一些比较特殊的类,希望在整个软件中只存在该类的一个对象(实例)。以闯关打斗类游戏为例,策划要求游戏中有一些配置选项,能够对游戏的声音大小、图像质量等进行配置,为此,要创建一个游戏配置相关的类 GameConfig,代码如下:

// 游戏配置相关类
class GameConfig {// …待增加
};

为了使用该类,需要创建该类相关的对象,于是,可以通过下面的代码创建一个类对象:

GameConfig g_config1;

当然,还可以创建该类的另外一个对象,甚至还可以创建更多的该类对象:

GameConfig g_config2;

但从项目需求来讲,整个游戏中只应该存在一个 GameConfig 类对象(对象可以在栈上创建也可以用 new 在堆上创建),该对象相当于一个全局的 GameConfig 类对象,统管游戏的配置。创建多个 GameConfig 类对象可能会造成混乱或程序逻辑不正确(也可能造成性能问题)。

单件类的设计原则

C++ 软件开发专家 Scott Meyers 曾经说过:“要使接口或者类型易于正确使用,难以错误使用。” 因此,保证类的单一实例化应该由类的设计者实现,而非依赖使用者的自律。

单件类的实现代码

// 游戏配置相关类
class GameConfig {
private:GameConfig() {};GameConfig(const GameConfig& tmpobj);GameConfig& operator=(const GameConfig& tmpobj);~GameConfig() {};public:static GameConfig* getInstance() {if (m_instance == nullptr) {m_instance = new GameConfig();}return m_instance;}private:static GameConfig* m_instance;  // 指向本类对象的指针
};GameConfig* GameConfig::m_instance = nullptr;  // 类外初始化静态成员变量

关键设计点

  1. 私有构造函数:禁止在类外部创建对象(包括栈和堆)。

    GameConfig* g_gc = new GameConfig;  // 非法
    GameConfig gc;                      // 非法
    
  2. 静态工厂方法:通过 getInstance() 创建唯一实例,首次调用时初始化。

  3. 禁止拷贝和赋值

    GameConfig g_gc3(*g_gc);   // 非法(拷贝构造)
    (*g_gc2) = (*g_gc);       // 非法(拷贝赋值)
    
  4. 私有析构函数:禁止外部手动释放对象。

    delete g_gc2;  // 非法
    

7.2 单件类在多线程中可能导致的问题

若多个线程同时调用 getInstance(),可能导致 多次实例化。例如:

  • 线程 1 执行 if (m_instance == nullptr) 后被挂起。
  • 线程 2 同样通过条件判断并创建实例。
  • 线程 1 恢复后再次创建实例,导致两个对象存在。

解决方案 1:加锁

static GameConfig* getInstance() {std::lock_guard<std::mutex> gcguard(my_mutex);  // 加锁if (m_instance == nullptr) {m_instance = new GameConfig();}return m_instance;
}

缺点:每次调用都需加锁,影响性能(仅首次初始化需要保护)。

解决方案 2:双重锁定(Double-Check Locking)

static GameConfig* getInstance() {if (m_instance == nullptr) {  // 第一重检查(无锁)std::lock_guard<std::mutex> lock(m_mutex);  // 加锁if (m_instance == nullptr) {  // 第二重检查(加锁后)m_instance = new GameConfig();}}return m_instance;
}

潜在问题:内存访问重排序可能导致未初始化的对象被使用(需结合 std::atomic 和内存栅栏解决)。

推荐方案

主线程 中提前初始化单件对象,避免多线程竞争:

int main() {GameConfig::getInstance();  // 提前初始化// 创建其他线程...return 0;
}

7.3 饿汉式与懒汉式

单件类的初始化方式分为两种:

饿汉式(Eager Initialization)

特点:程序启动时立即创建实例,线程安全。

class GameConfig {static GameConfig* m_instance = new GameConfig();  // 类外直接初始化
};

缺点:可能提前消耗资源(即使未使用)。

懒汉式(Lazy Initialization)

特点:首次调用 getInstance() 时创建实例,延迟加载。

class GameConfig {static GameConfig* getInstance() {if (m_instance == nullptr) {m_instance = new GameConfig();}return m_instance;}
};

缺点:多线程下需额外处理同步问题。

7.4 单件类对象内存释放问题

单件对象的生命周期通常与程序一致,但可通过以下方式手动释放:

方案 1:手动调用释放函数

class GameConfig {
public:static void freeInstance() {if (m_instance != nullptr) {delete m_instance;m_instance = nullptr;}}
};

方案 2:嵌套类自动释放(Garbo 模式)

class GameConfig {
private:class Garbo {public:~Garbo() {if (GameConfig::m_instance != nullptr) {delete GameConfig::m_instance;GameConfig::m_instance = nullptr;}}};static Garbo garboobj;  // 静态嵌套类对象
};GameConfig::Garbo GameConfig::garboobj;  // 类外初始化

原理:静态对象 garboobj 的析构函数会在程序结束时自动调用,释放单件对象。

7.5 单件类定义、UML 图及另外一种实现方法

单件模式定义

意图:保证一个类仅有一个实例,并提供全局访问点。

UML 图

GameConfig
-_m_instance: GameConfig // 静态成员
+getInstance()
-GameConfig()

另一种实现:返回局部静态变量引用

class GameConfig {
private:GameConfig() {};~GameConfig() {};public:static GameConfig& getInstance() {static GameConfig instance;  // 局部静态变量return instance;}
};

优点

  • 代码简洁,自动处理线程安全(C++11 保证局部静态变量初始化的线程安全)。
  • 实例在首次调用时创建,析构在程序结束时自动执行。

总结

  • 单件类 vs 全局变量:单件类通过封装保证单一实例,全局变量无法阻止多实例。
  • 多线程注意事项:优先在主线程初始化,或使用 C++11 局部静态变量特性。
  • 扩展限制:单件类难以继承,需谨慎设计。

文章转载自:

http://u8bq4pk2.synkr.cn
http://raemWF0h.synkr.cn
http://UMvv9ZMx.synkr.cn
http://rH7IvwZp.synkr.cn
http://aEkscoHS.synkr.cn
http://ZIYNWO8h.synkr.cn
http://4GbJUTsC.synkr.cn
http://jaCNFUyM.synkr.cn
http://Qo9qhLUG.synkr.cn
http://Mcg2sNJj.synkr.cn
http://rcxOfMnY.synkr.cn
http://WmJjeFuD.synkr.cn
http://VOA0GbxA.synkr.cn
http://V15xLbel.synkr.cn
http://PsY2HCF5.synkr.cn
http://6O6QH433.synkr.cn
http://2ugqAkDT.synkr.cn
http://HnJiZ96V.synkr.cn
http://5Rdhd6EW.synkr.cn
http://FaOFioD3.synkr.cn
http://x0GYpvPK.synkr.cn
http://QhncfHjR.synkr.cn
http://MdTFuz5T.synkr.cn
http://v3P4r7gq.synkr.cn
http://2gk9fUOb.synkr.cn
http://KuhMS9JO.synkr.cn
http://9h2tqZda.synkr.cn
http://yN5RZ2r3.synkr.cn
http://BCcC6QQu.synkr.cn
http://gVFb5AyG.synkr.cn
http://www.dtcms.com/wzjs/722841.html

相关文章:

  • 小说网站怎么做词iis 做网站
  • 门户网站通俗理解智能建站系统cms
  • 网上做兼职正规网站网站视频源码地址
  • 泰安网站优化简单的手机app制作流程
  • 乔拓云建站平台西安到北京
  • 网站如何推广行业网站建设项目进度计划书
  • 电子商务网站开发 pdf移动互联网开发大作业
  • 小程序推广网站个人网站开发要多久
  • 网站建设主要工作流程西安设计工作室
  • 网络违法犯罪举报网站网页设计板式网站
  • 小型网站用typescript南阳专业网站建设价格
  • 网站可以做充值吗北京丰台网站建设
  • 西安巨久科技网站建设校园网站建设培训稿
  • 网站建设在医院的作用百度app浏览器下载
  • 有服务器了怎么做网站营销型网站建设市场分析
  • wordpress个人网站后台登陆西安网站制作顶尖公司
  • 饰品网站模板网页游戏制作教程
  • 成都动力无限 网站 差网站建设官方商城
  • 绵阳网站建设怎么做贵州城乡住房和建设厅网站
  • 如何建立公司网站南通佛山附近做网站的公司
  • 网络营销的主要形式有建设网站兴安盟seo
  • 动漫做a视频网站win10优化
  • 河东区腾讯网站建设华为云云速建站
  • 网站员工风采深圳建筑设计师招聘信息
  • dw做的网站怎么放到服务器上个人网站代码编写
  • 成立门户网站建设工作小组给教育类做网站
  • 大连 网站wordpress怎么引用新浪ajax
  • 个人建立网站后怎么盈利做家教网站
  • 平顶山做网站的公司搭建一个网站需要哪些技术
  • 建设网站费用分析国外媒体报道