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

蓝色网站素材wordpress首页聚合模块

蓝色网站素材,wordpress首页聚合模块,新乡建设工程信息网站,移动平台3g手机网站前端开发布局技巧汇总单例模式:保证在整个程序中,某个类只有一个实例,并且可以全局可访问。换句话说:整个类只想要一个对象全局都可以使用这个对象不允许创建第二个对象再比如: 程序的配置管理器(只需要一个)日志系统…

单例模式:保证在整个程序中,某个类只有一个实例,并且可以全局可访问。

换句话说:

整个类只想要一个对象

全局都可以使用这个对象

不允许创建第二个对象

再比如:
程序的配置管理器(只需要一个)

日志系统(写日志的对象只有一个)

数据库连接池(共享同一个)

想用全局变量(虽然用单例模式也不太好)

懒汉单例(c++11后)

#include <iostream>
#include <mutex>class Singleton {
public:// 获取唯一实例的全局访问点static Singleton& getInstance() {static Singleton instance; // C++11保证线程安全return instance;}void doSomething() {std::cout << "我是唯一的实例,正在工作..." << std::endl;}private:// 构造函数私有,禁止外部 newSingleton() {std::cout << "单例对象创建成功!" << std::endl;}// 禁止拷贝和赋值Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;
};int main() {// 获取唯一实例Singleton& s1 = Singleton::getInstance();Singleton& s2 = Singleton::getInstance();s1.doSomething();// 检查是否是同一个对象if (&s1 == &s2) {std::cout << "s1 和 s2 是同一个实例" << std::endl;}return 0;
}

结果:

单例对象创建成功!
我是唯一的实例,正在工作...
s1 和 s2 是同一个实例

懒汉单例 vs 饿汉单例

在 C++ 中,常见的单例实现分为两种:

特性懒汉单例(Lazy Singleton)饿汉单例(Eager Singleton / 普通单例)
创建时机第一次使用 getInstance() 时才创建程序启动时就创建
资源使用节省资源,只有需要时才创建程序一启动就分配资源,可能会浪费
线程安全C++11 以后用 static 自动线程安全程序启动前初始化,天然线程安全
实现难度稍微复杂,需要考虑懒加载非常简单,直接静态初始化
性能首次访问时稍慢,但之后一样快程序启动时有初始化开销,访问快
适用场景创建代价大、偶尔使用的对象创建代价小、经常使用的对象

懒汉单例的实现:

class LazySingleton {
public:static LazySingleton& getInstance() {static LazySingleton instance; // 第一次调用时创建return instance;}
private:LazySingleton() {}LazySingleton(const LazySingleton&) = delete;LazySingleton& operator=(const LazySingleton&) = delete;
};

只有第一次调用getInstance()才会创造对象

如果程序没有用到这个对象,就不会浪费资源

适合“可能用,也可能不用”的场景

饿汉单例的实现:

class EagerSingleton {
public:static EagerSingleton& getInstance() {return instance;}
private:EagerSingleton() {}static EagerSingleton instance;  // 程序启动时就创建
};EagerSingleton EagerSingleton::instance;  // 定义并初始化

程序一启动就会创造对象

初始化顺序再程序启动阶段完成

适合“肯定会用”的场景,比如日志系统,配置管理器

static EagerSingleton instance;  写在类外,会在程序启动时就创建

tips:

能用单例不用全局变量,能不用单例就不用单例

单例模式不仅仅是“全局变量”,它还带来更好的封装性、控制力和安全性

特性全局变量单例模式
内存控制程序一启动就分配可以懒加载,按需创建
封装性所有人可以直接改值对象私有,接口可控
可维护性容易被误用提供统一访问入口
多实例风险程序员可以随便 new 多个禁止拷贝、赋值,确保唯一
线程安全需要自己管理C++11 的懒汉式默认安全
可扩展性改逻辑要修改全局代码可以封装到类里,扩展方便

那为什么能不用单例就不用单例

单例缺点:

1.单例的本质就是全局变量,说单例不好就是说全局变量不好。

全局状态会带来问题:

  • 难以追踪谁修改了它

  • 如果多人同时修改,可能出现不可预期的行为

  • 线程安全变复杂

2.难以进行单元测试

举个例子,有一个 Database 单例:

Database& db = Database::getInstance();
db.connect("mysql://...");

问题来了:

  • 如果我要写一个测试用例,让 Database 不连接真实的 MySQL,而是用一个假数据库(Mock Database),怎么办?

  • 单例让“依赖注入”变得困难,因为你无法轻易替换内部对象。

如果是普通类,我们可以这样:

class MyService {
public:MyService(Database* db) : db_(db) {}   // 构造函数,传入数据库对象指针void work() { db_->query("SELECT 1"); } // 调用数据库执行查询
private:Database* db_;                         // 保存数据库对象指针
};

测试时:

MockDatabase mockDb;
MyService service(&mockDb);  // 传入假的db

如果用单例,就很难做到这一点 → 这就是很多书批评单例的原因。

3.生命周期难管理

单例通常使用静态变量,比如:

static Logger& getInstance() {static Logger instance;return instance;
}

这个对象会在程序退出时自动销毁,但如果在其他全局对象的析构函数中访问 Logger,可能会出现“对象已被销毁”的错误。

静态对象的销毁顺序

在 C++ 中,静态对象(static 对象)的生命周期是:

  1. 程序运行到第一次使用它时创建(懒汉)或程序启动就创建(饿汉)

  2. 程序退出时会自动销毁(调用析构函数)

例如:

class Logger {
public:Logger() { std::cout << "Logger创建\n"; }~Logger() { std::cout << "Logger销毁\n"; }void log(const std::string& msg) { std::cout << msg << std::endl; }
};int main() {static Logger logger;logger.log("Hello");return 0;
}
  • logger 对象会在 main() 结束后自动销毁

  • 析构函数 ~Logger() 会被调用

问题出现的场景

假设你还有另一个全局对象:

class GlobalObject {
public:~GlobalObject() {Logger::getInstance().log("GlobalObject析构");}
};GlobalObject g_obj;  // 全局对象

程序运行顺序:

  1. main() 结束,静态对象开始销毁

  2. 全局对象 g_obj 的析构函数先执行

  3. 析构函数里调用 Logger::getInstance().log()

问题来了:

  • 如果 Logger 是静态对象(比如懒汉单例的 static Logger instance;

  • 它的析构函数可能已经被调用(对象已销毁)

  • 这时再调用 log()访问已销毁的对象 → 未定义行为 → 程序可能崩溃

在大型C++项目中,这个问题被称为 Static Initialization Order Fiasco(静态初始化顺序灾难)。
如果用普通类+依赖注入,可以更好地控制对象的生命周期。

4.隐式耦合,降低可维护性

单例是一种全局可见的状态,导致“想改一处,动全局”:

  • 你在某个地方修改了单例的状态

  • 另一个模块突然行为异常

  • 你完全不知道问题出在哪

如果改用依赖注入(把需要的对象通过构造函数传递),模块之间的依赖会更明确。

原因解释
全局状态单例本质是“全局变量”,会导致数据混乱
难测试单元测试很难替换单例对象
生命周期不可控静态对象销毁顺序不受控制
隐式耦合模块间依赖隐藏在单例中,难以维护
多线程风险

如果用C++98或旧代码,线程安全很难保证

不适合用单例

  1. 数据缓存

    如果缓存只是某个功能模块使用,用类成员更好
  2. 临时状态管理

    比如某个页面的UI状态,不需要全局唯一
  3. 可扩展性要求高

    如果未来有一天可能需要多个实例,提前用单例会很难改

替代方案

如果能不用单例,常见的替代方案有:

(1) 依赖注入(Dependency Injection)

不要在类内部自己创建或固定依赖,把依赖从外部传进来。

拿刚刚的数据库举例子来说,"mysql://..." 写在代码里就是 硬编码,你要测试改数据库就必须改那段源码。

class Logger {
public:void log(const std::string& msg); //用来打印或记录日志
};class Service {
public:Service(Logger* logger) : logger_(logger) {} // 把传进来的 logger 参数 赋值给类成员变量 logger_void run() { logger_->log("running"); }  // 成员函数
private:Logger* logger_;   //成员变量
};int main() {Logger logger; //创建一个Logger对象Service service(&logger);  // 明确注入依赖,把logger的地址传进去,service就可以使用这个loggerservice.run(); // Service调用Logger的log()方法
}

Service 类解析

  1. 成员变量 Logger* logger_

    • 指向一个 Logger 对象的指针

    • 用来在 Service 内部调用 Logger 的功能

  2. 构造函数 Service(Logger* logger)

    • 接收一个 Logger 对象指针作为参数

    • 初始化成员变量 logger_

    • 核心思想:Service 不负责创建 Logger,而是使用外部提供的 Logger → 这就是“依赖注入”

  3. : logger_(logger)初始化列表

    把传进来的 logger 参数 赋值给类成员变量 logger_
  • Service依赖 一个 Logger 对象来记录日志

  • Service 自己不创建 Logger,而是通过构造函数 外部传入 一个 Logger 对象

  • main() 函数创建 Logger 对象,再传给 Service 使用

好处:

  • 测试更容易(可以传入Mock对象(用于测试的假对象))

  • 生命周期由你控制

  • 模块之间的依赖明确

(2) 把对象放到 main() 里

有些时候,其实你只需要在 main() 里创建一个对象,然后把它传递给需要的地方,完全不需要全局变量或单例。

http://www.dtcms.com/a/510907.html

相关文章:

  • 导购类网站模板做零食网站的首页模板
  • 怀集县住房和城乡规划建设网站肇庆seo外包
  • 辽宁品牌建设促进会 网站潍坊高端网站设计
  • 网站免费申请优化设计七年级下册语文答案
  • 网站备案回访电话号码网站建设mdf
  • 网站登录页做多大尺寸的网站系统升级
  • 江西建网站镇江润州区建设局网站
  • 国际知名的论文网站重庆公司注销流程
  • 专做网页的网站可以做拟合的在线网站
  • 广东网站开发项目网页设计的基本原则
  • 北京做网站制作的公司什么视图适用于发送电子邮件和创建网页
  • 成都网站建设 3e房地产新闻最新消息今天
  • 织梦网站源码转换成wordpress厦门35网站建设公司
  • 昆明市城市基本建设档案馆网站上海网站备案需要多久
  • 网站建设与功能模块网站视频解析
  • 网站制作备案上线流程仿造网站用侵权吗
  • 网站备案人什么意思石家庄百度搜索优化
  • 番禺区网站建设满分企业网
  • 福州网站建设找嘉艺网络集团公司网站源码下载
  • iis7搭建asp网站常德百度seo
  • php网站建立教程精美网页源码网站
  • 北大荒建设集团网站步骤怎么写
  • 如何让网站收录公司名深圳网络推广外包
  • 泉州网站优化排名程序员自己做网站怎么能来钱
  • 鹿泉专业网站建设网页制作考试题及答案
  • 安庆做网站网站代理学计算机工资一月多少
  • 网站如何能吸引用户西昌seo快速排名
  • 公益广告 公司网站建设中...虚拟空间软件
  • 网站建设项目外包服务器上网站建设
  • 温州瑞安网站建设平台龙泉驿最新消息