欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 锐评 > C++单例模式

C++单例模式

2025/12/14 11:59:02 来源:https://blog.csdn.net/2301_76197086/article/details/145457263  浏览:    关键词:C++单例模式

单例模式是一种设计模式,它保证一个类只有一个对象。因此单例模式要私有化构造函数,禁用拷贝构造以及赋值重载。同时还要提供一个静态成员函数获取单例对象。

单例模式有两种实现方式:饿汉模式和懒汉模式

饿汉模式:创建静态单例对象,它在编译期间就被初始化,即在main函数执行之前就初始化

优点:线程安全,因为单例对象在main函数执行之前就初始化完成,不存在多线程竞争初始化单例对象的问题

缺点:占用资源,因为单例对象初始化时可能会加载许多其他资源,导致进程启动慢


懒汉模式:创建静态单例对象指针,实现延迟加载,只有在第一次请求单例对象时才初始化

优点:延迟初始化,避免加载不必要的资源

缺点:线程不安全,如果没有线程同步机制,可能会导致多个线程竞争初始化单例对象问题

1.饿汉模式

//饿汉模式
class ConfigInfo
{
private:static ConfigInfo _info;//静态单例对象std::string _ip = "127.0.0.1";int _port = 8080;
private://私有化构造函数ConfigInfo() {}
public://禁用拷贝构造ConfigInfo(const ConfigInfo& info) = delete;//禁用赋值重载ConfigInfo& operator=(const ConfigInfo& info) = delete;//静态成员函数,返回单例对象指针static ConfigInfo* GetInstance(){return &_info;}//获取IP地址std::string GetIP(){return _ip;}//设置IP地址void SetIP(std::string ip){_ip = ip;}
};
//静态单例对象的类外定义
ConfigInfo ConfigInfo::_info;
int main()
{ConfigInfo* info = ConfigInfo::GetInstance();std::cout << info->GetIP() << std::endl;info->SetIP("127.4.6.34");std::cout << info->GetIP() << std::endl;return 0;
}

2.懒汉模式

GetInstance函数中判断_info==nullptr会有线程安全问题:假设两个线程都成功进入了if内部,就会多次new分配资源,因此要进行加锁。加锁后又存在性能问题:
每个线程到此处都要进行加锁解锁,但实际上单例对象只有在第一次被调用时才会被判断为空并进行new资源分配,往后再被调用时一定不为nullptr。所以只要在得一次调用时进行加锁即可,这里要进行双检查加锁。

//懒汉模式
class ConfigInfo
{
private:static ConfigInfo* _info;//静态单例对象std::string _ip = "127.0.0.1";int _port = 8080;static std::mutex _mtx;//静态锁
private://私有化构造函数ConfigInfo() {}
public://禁用拷贝构造ConfigInfo(const ConfigInfo& info) = delete;//禁用赋值重载ConfigInfo& operator=(const ConfigInfo& info) = delete;//静态成员函数,返回单例对象指针static ConfigInfo* GetInstance(){//此处判断_info==nullptr会有线程安全问题:假设两个线程都成功进入了if内部,就会多次new分配资源//因此要进行加锁//加锁后又存在性能问题://每个线程到此处都要进行加锁解锁,但实际上单例对象只有在第一次被调用时才会被判断为空并进行new资源分配,往后再被调用时一定不为nullptr//所以只要在得一次调用时进行加锁即可//这里要进行双检查加锁if (_info == nullptr){std::unique_lock<std::mutex> lock(_mtx);if (_info == nullptr){_info = new ConfigInfo;}}return _info;}//获取IP地址std::string GetIP(){return _ip;}//设置IP地址void SetIP(std::string ip){_ip = ip;}
};
//静态单例对象的类外定义
ConfigInfo* ConfigInfo::_info = nullptr;
//静态锁类外定义
std::mutex ConfigInfo::_mtx;
int main()
{ConfigInfo* info = ConfigInfo::GetInstance();std::cout << info->GetIP() << std::endl;info->SetIP("127.4.6.34");std::cout << info->GetIP() << std::endl;return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词