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

四川网站建设的公司排名免费推广网站排行榜

四川网站建设的公司排名,免费推广网站排行榜,中国建设银行济南招聘信息网站,个人如何开发手机app引言 设计模式在软件开发中扮演着至关重要的角色,然而,没有一种设计模式是完美无缺的,单例设计模式便是其中之一。它一直以来都备受争议,有人认为它是解决特定问题的有效方案,也有人觉得它存在诸多弊端。在实际应用中…

在这里插入图片描述

引言

设计模式在软件开发中扮演着至关重要的角色,然而,没有一种设计模式是完美无缺的,单例设计模式便是其中之一。它一直以来都备受争议,有人认为它是解决特定问题的有效方案,也有人觉得它存在诸多弊端。在实际应用中,我们需要根据具体问题和项目需求来判断是否选择单例模式。

单例模式概述

单例模式是一种创建型设计模式,主要关注对象的创建方式。其核心思想是确保在一个程序中,某个类只能有一个实例存在,并且提供一个全局访问点来获取这个实例。

以 C++ 语言为例,通常情况下,我们创建一个类的对象时可以多次实例化。比如创建一个名为 Type 的类:

class Type {// 类的成员和方法
};

我们可以在程序中多次实例化这个类的对象:

Type myObject1;
Type myObject2;

但在单例模式下,我们需要限制只能创建一个该类的实例。

实现单例模式的步骤

初始尝试

为了演示单例模式,我们创建一个简单的日志类 Logger。首先,我们按照常规方式创建这个类,包含构造函数、析构函数、拷贝构造函数和赋值运算符:

#include <iostream>class Logger {
public:Logger() {std::cout << "Logger was created" << std::endl;}~Logger() {// 析构函数代码}Logger(const Logger&) = default;Logger& operator=(const Logger&) = default;
};

main 函数中,我们可以多次创建 Logger 类的对象:

int main() {Logger logger1;Logger logger2;Logger logger3;Logger logger4;return 0;
}

编译并运行这个程序,我们会看到多次输出 “Logger was created”,这表明创建了多个 Logger 实例。

限制对象创建

为了实现单例模式,我们需要限制对象的创建。一个简单的方法是将构造函数设为私有:

class Logger {
private:Logger() {std::cout << "Logger was created" << std::endl;}~Logger() {// 析构函数代码}Logger(const Logger&) = default;Logger& operator=(const Logger&) = default;
};

此时,如果我们尝试在 main 函数中创建 Logger 对象,编译器会报错,因为构造函数是私有的,外部无法直接调用。

提供全局访问点

为了能够获取 Logger 类的唯一实例,我们需要提供一个公共的成员函数 getInstance

class Logger {
private:Logger() {std::cout << "Logger was created" << std::endl;}~Logger() {// 析构函数代码}Logger(const Logger&) = default;Logger& operator=(const Logger&) = default;static Logger* s_instance;public:static Logger* getInstance() {if (s_instance == nullptr) {s_instance = new Logger();}return s_instance;}
};Logger* Logger::s_instance = nullptr;

main 函数中,我们可以通过 getInstance 函数来获取 Logger 类的唯一实例:

int main() {Logger* logger = Logger::getInstance();return 0;
}

静态关键字的使用

在单例模式中,静态关键字 static 起着关键作用。静态变量的生命周期是整个程序的运行期间,并且只会被初始化一次。

例如,我们可以在 Logger 类中添加一个静态成员变量 numberOfLoggers 来记录创建的 Logger 实例数量:

class Logger {
private:Logger() {std::cout << "Logger was created, number of loggers: " << numberOfLoggers << std::endl;numberOfLoggers++;}~Logger() {// 析构函数代码}Logger(const Logger&) = default;Logger& operator=(const Logger&) = default;static int numberOfLoggers;public:static Logger* getInstance() {if (s_instance == nullptr) {s_instance = new Logger();}return s_instance;}
};int Logger::numberOfLoggers = 0;

需要注意的是,静态成员变量必须在类外部进行初始化。

完善日志类功能

为了让 Logger 类更具实用性,我们可以添加一些成员函数,如 addMessage 用于添加日志消息,printMessages 用于打印所有日志消息:

#include <iostream>
#include <vector>
#include <string>class Logger {
private:Logger() {std::cout << "Logger was created" << std::endl;}~Logger() {// 析构函数代码}Logger(const Logger&) = default;Logger& operator=(const Logger&) = default;static Logger* s_instance;std::vector<std::string> messages;public:static Logger* getInstance() {if (s_instance == nullptr) {s_instance = new Logger();}return s_instance;}void addMessage(const std::string& message) {messages.push_back(message);}void printMessages() {for (const auto& message : messages) {std::cout << message << std::endl;}}
};Logger* Logger::s_instance = nullptr;

main 函数中,我们可以使用这些功能:

int main() {Logger* logger = Logger::getInstance();logger->addMessage("hello message1");logger->addMessage("hello message2");logger->addMessage("hello message3");logger->printMessages();return 0;
}

单例模式的问题与改进

指针返回的风险

在上述实现中,getInstance 函数返回的是一个指针。这可能会带来一些问题,例如用户可能会意外删除这个指针,导致单例对象被销毁。为了避免这种情况,我们可以返回一个引用而不是指针:

class Logger {
private:Logger() {std::cout << "Logger was created" << std::endl;}~Logger() {// 析构函数代码}Logger(const Logger&) = default;Logger& operator=(const Logger&) = default;static Logger* s_instance;std::vector<std::string> messages;public:static Logger& getInstance() {static Logger instance;return instance;}void addMessage(const std::string& message) {messages.push_back(message);}void printMessages() {for (const auto& message : messages) {std::cout << message << std::endl;}}
};

main 函数中,我们可以这样使用:

int main() {Logger& logger = Logger::getInstance();logger.addMessage("hello message1");logger.addMessage("hello message2");logger.addMessage("hello message3");logger.printMessages();return 0;
}

多线程考虑

在多线程环境下,单例模式可能会出现问题。例如,多个线程同时调用 getInstance 函数时,可能会创建多个实例。为了保证线程安全,我们可以使用互斥锁(mutex)来保护 getInstance 函数:

#include <iostream>
#include <vector>
#include <string>
#include <mutex>class Logger {
private:Logger() {std::cout << "Logger was created" << std::endl;}~Logger() {// 析构函数代码}Logger(const Logger&) = default;Logger& operator=(const Logger&) = default;static Logger* s_instance;static std::mutex mtx;std::vector<std::string> messages;public:static Logger& getInstance() {std::lock_guard<std::mutex> lock(mtx);if (s_instance == nullptr) {s_instance = new Logger();}return *s_instance;}void addMessage(const std::string& message) {messages.push_back(message);}void printMessages() {for (const auto& message : messages) {std::cout << message << std::endl;}}
};Logger* Logger::s_instance = nullptr;
std::mutex Logger::mtx;

总结

单例模式是一种强大的设计模式,它可以确保一个类只有一个实例,并提供全局访问点。然而,它也存在一些问题,如全局状态的引入、多线程安全问题以及可测试性降低等。在使用单例模式时,我们需要权衡其优缺点,并根据具体情况进行选择。同时,我们还需要注意代码的实现细节,避免出现潜在的问题。希望通过本文的介绍,你能对单例模式有更深入的理解,并在实际开发中合理运用。

http://www.dtcms.com/wzjs/517930.html

相关文章:

  • 牛网网站建设微信管理软件哪个最好
  • 做网站接单渠道360竞价推广客服电话
  • php盗版视频网站怎么做的培训机构专业
  • wordpress建站教程新手百度pc端网页版
  • wordpress问答站模板阿里云搜索
  • 专业网站制作企业seo搜索引擎优化知乎
  • 网站备案 类型百度在线提问
  • 企业网站备案流程搜索引擎营销例子
  • 做网站推广怎么做网络营销的策略有哪些
  • 申请免费网站空间网络营销咨询公司
  • 高端网站建设哪些好做网站查询是否安全
  • 有些网站突然无法访问长沙 建站优化
  • qq自动发货平台网站怎么做seo推广外包
  • 外贸高端网站建设客服外包平台
  • 微信公众号对接网站如何做自助建站系统
  • 怎么做网站的访问量北京刚刚传来特大消息
  • seo网站营销推广海外推广渠道都有哪些
  • wordpress政府网站主题 中文如何免费做网站网页
  • 网站备案注意太原百度公司地址
  • 帮人做兼职的网站搜索引擎优化seo论文
  • 诚信通网站怎么做外链互联网销售模式
  • 网站 文件验证企业管理培训
  • asp.net+制作网站开发关键词优化哪家强
  • 江苏网络公司网站建设创建网址快捷方式
  • 怎么使用网站服务器杭州正规引流推广公司
  • 做网站都需要服务器吗北京软件培训机构前十名
  • 网站建设包装策略常用的网络营销方法及效果
  • 网站制作html和css查域名
  • 建个人网站做导购怎么备案小红书seo排名规则
  • 龙岗营销网站建设公司网站seo诊断分析和优化方案