C++ 单例模式 模版类(Meyers‘ Singleton)_meyers' singleton 模板类-程序员宅基地

技术标签: C++ Meyers' Singleton  C/C++  For Interview  C++单例模式模板类  C++单例模式  Design Pattern  

自己实现的Meyers’ Singleton的单例模式模板类。

1 不继承

具体类无需继承, 使用Singleton<Test>::getInstance()获得唯一实例。

template<typename T>
class Singleton
{
    
private:
	Singleton() = default;  // 设置为私有(protected也行),禁止外部直接构造

public:
	Singleton(const Singleton&) = delete; // 禁止拷贝构造
	Singleton& operator = (const Singleton&) = delete; // 禁止拷贝赋值
	~Singleton() = default;

public:
	static T& getInstance() //  Meyers' Singleton 
	{
    
		static T instance;
		return instance;
	}
};

class Test
{
    
public:
	Test() = default;
	~Test() = default;

public:
	void Func() {
     std::cout << "Test::Func()" << std::endl; }
};

#define TestInstance Singleton<Test>::getInstance() // 这里注意没有分号

调用如下:

int main()
{
    
	TestInstance.Func();
	return 0;
}

这种实现方式简单、方便,无需继承。
由于无需继承,通过Test类声明无法知道该类为单例类,意义不明确。
由于Singleton中需要调用Test的构造函数,所以必须将其声明为public。这会导致无法阻止外部直接构造Test对象。

2 继承

template<typename T>
class Singleton
{
    
public:
	~Singleton() = default;

	static T& getInstance() //  Meyers' Singleton 
	{
     
		static T instance;
		return instance;
	}

private:
	Singleton(const Singleton&) = delete; // 禁止拷贝构造
	Singleton& operator = (const Singleton&) = delete; // 禁止拷贝赋值

protected: // 允许被继承类调用
	Singleton() = default;  // 设置为私有,禁止外部直接构造
};

class Test : public Singleton<Test>
{
    
public:
	void Func() {
     std::cout << "Test::Func()" << std::endl; }

public: // 只能为public,否则编译报错,不能阻止外部调用
	Test() = default;
};

#define TestInstance Test::getInstance()

Test继承Singleton,通过类声明就知道Test是个单例类。但是构造函数依然只能声明为public,导致外部依旧能直接调用构造Test对象。

3 继承+友元

template<typename T>
class Singleton
{
    
public:
	friend typename T; // 友元声明

public:
	~Singleton() = default;

	static T& getInstance() //  Meyers' Singleton 
	{
     
		static T instance;
		return instance;
	}

private:
	Singleton(const Singleton&) = delete; // 禁止拷贝构造
	Singleton& operator = (const Singleton&) = delete; // 禁止拷贝赋值

private:
	Singleton() = default;  // 设置为私有,禁止外部直接构造
};

class Test : public Singleton<Test>
{
    
public:
	friend class Singleton<Test>;  // 友元声明

public:
	void Func() {
     std::cout << "Test::Func()" << std::endl; }

private: // 构造函数可以声明为private,阻止外部直接调用
	Test() = default;
};

#define TestInstance Test::getInstance()

通过相互声明为友元,Test的构造函数即使声明为private,Singleton的依旧能访问其构造函数,不会编译报错。
同时private阻止外部直接构造Test对象,只能通过Test::getInstance()获取唯一实例。当然,这就要求新类继承自Singleton时必须将Singleton声明自己的友元类。

4 继承+友元(小改版)

template<typename T>
class Singleton
{
    
protected: // 不能直接构造,同时子类可访问,这是protected的优势
	Singleton() = default;

public: // 不提供拷贝构造函数和赋值函数
	Singleton(const Singleton& one) = delete;
	Singleton& operator=(const Singleton& one) = delete;

public: // 全局访问函数
	static T& GetInstance()
	{
    
		static T instance;
		return instance;
	}
};

class Test : public Singleton<Test> // 继承自Singleton<TestClass>
{
    
public: // 必须提供
	friend Singleton<Test>;

private: // 不能直接构造,也可使用protected
	Test() = default;

public:
	void TestFunc()
	{
    
	}
};

当Test继承子Singleton<Test>后,需要改动的地方有两处:

  • 声明Singleton<Test>为友元。
  • 声明构造函数为private或者protected。

感觉还是比较麻烦,想最终实现的功能是:一个类想要变成单例类,只需要继承自单例模板类即可,无需再做其他修改。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xp178171640/article/details/102699320

智能推荐

Mendix客户项目总结_mendix项目-程序员宅基地

文章浏览阅读983次。​从2005年成立至今,Mendix一直以客户价值为导向精心打磨产品,提升客户、合作伙伴及所有参与方的使用体验。进入中国以来,我们更是以120%的态度践行这一原则。工欲善其事必先利其器,这里的“器”不仅仅在于产品本身,更在于产品背后代表的思维方式,实施合作伙伴的培养与赋能,解决方案架构,项目管理与执行,客户数字化转型的长远的计划与思考等等。只有不断地用先进的理论指导实践,并在实践中迭代成长,才能充分发挥先进生产工具的最大价值,创造多方的共赢局面。因此,我们会建议Mendix客户针对第一期的开发项目认真地_mendix项目

MATLAB修改字体大小,加粗,字体样式,字体颜色,线形,希腊字母,特殊符号,图片文本位置及字体设置等_matlab字体-程序员宅基地

文章浏览阅读2.3w次,点赞41次,收藏255次。MATLAB修改字体大小,加粗,字体样式,字体颜色,线形颜色格式,添加标签,修改标签格式,希腊字母表,图片文本位置等_matlab字体

Spring环境配置(安装springsource-tool-suite插件)及第一个Spring HelloWorld-程序员宅基地

文章浏览阅读3.6k次。SpringSoource-tool-suite安装为了使用Spring的方便,首先Eclipse安装插件SpringSoource-tool-suite(SpringSoource-tool-suite 是一个基于EclipseIDE开发环境中的用于开发Spring应用程序的插件。利用这个插件,可以方便的在Eclipse平台上开发基于Spring框架的应用)。如下是SpringSoource-to_springsource-tool-suite

mysql 效率监控_zabbix监控mysql性能-程序员宅基地

文章浏览阅读156次。通过获取mysql状态值将这些状态值传递给服务器并绘制成图片,这样可以观察mysql的工作情况,通常需要获得状态变量有以下Com_update:mysql执行的更新个数Com_select:mysql执行的查询个数Com_insert:mysql执行插入的个数Com_delete:执行删除的个数Com_rollback:执行回滚的操作个数Bytes_received:接受的字节数Bytes_sen..._zabbix slow queries over 3 for 5m

正交法设计用例_四阶正交拉丁方阵-程序员宅基地

文章浏览阅读4.6k次,点赞3次,收藏14次。正交实验法的由来一、正交表的由来拉丁方名称的由来 古希腊是一个多民族的国家,国王在检阅臣民时要求每个方队中每行有一个民族代表,每列也要有一个民族的代表。数学家在设计方阵时,以每一个拉丁字母表示一个民族,所以设计的方阵称为拉丁方。什么是n阶拉丁方?用n个不同的拉丁字母排成一个n阶方阵(n<26 ),如果每行的n个字母均不相同,每列的n个字母均不相同,则称这种方阵为n*n拉丁方或n阶拉丁方。每个字母在任一行、任一列中只出现一次。_四阶正交拉丁方阵

细粒度情感分析在到餐场景中的应用_absa数据标注工具-程序员宅基地

文章浏览阅读3.6k次。总第482篇2021年 第052篇经典的细粒度情感分析(ABSA,Aspect-based Sentiment Analysis)主要包含三个子任务,分别为属性抽取、观点抽取以及属性-观点..._absa数据标注工具

随便推点

PWA登陆iOS了,但它还有这些缺陷_pwa的缺点-程序员宅基地

文章浏览阅读2.1k次。Apple 在 iOS 11.3 中悄悄加入了对“渐进式 Web 应用”(PWA)这一系列新技术的基本支持。是时候看看这些技术是如何生效的?它有什么能力?会遇到哪些挑战?以及如果已经发布了 PWA,又需要了解哪些事情?本文概括介绍了最新发布的 iOS 11.3 对 PWA 的支持情况,以及 PWA 应用开发者需要注意的问题。本文转载自前端之巅作者 Maximiliano Firtman..._pwa的缺点

Qt 加载图片文件路径详解_qt资源图片路径-程序员宅基地

文章浏览阅读7.6k次,点赞3次,收藏23次。QT 加载文件,图片路径很容易搞混,需要注意的是WINDOW路径分隔符为“\”,QT为“/”,我遇到的路径加载总结为三种情况:(1)绝对路径,文件的整个路径,比如 setWindowIcon(QIcon("F:/QT_PROJECT/QTtest/test/res/123.jpg"));//加载图片绝对路径(2)相对路径 1.第一种情况,新建QT 资源文件,也就..._qt资源图片路径

wanchain是个什么样的项目_wanchain与delphy都是同一个团队的项目吗?你们是不是来圈钱的?-程序员宅基地

文章浏览阅读1.4k次。万维链旨在建立一个分布式的未来“银行”,万维链本身是一个分布式的基于数字资产的金融基础设施,任何机构和个人,都可以在万维链上开设自己的业务窗口,提供基于数字资产的存贷、兑换、支付、结算等服务。更加准确的描述,万维链是一个基于区块链的分布式超级金融市场。_wanchain与delphy都是同一个团队的项目吗?你们是不是来圈钱的?

Linux 系统下搭建 Gitlab 服务器-程序员宅基地

文章浏览阅读2.7k次。1、安装依赖工具// 安装技术依赖yum install -y curl policycoreutils-python openssh-server // 启动ssh服务/设置为开机启动sudo systemctl enable sshdsudo systemctl start sshd2、安装 Postfix 邮件服务器// 安装 postfixsudo yum ins..._linux 安装gitlab服务器

LiveNVR配置拉转RTSP传统海康大华安防摄像机直播流输出RTSP/RTMP/HLS/HTTP-FLV如何获取直播流地址_公网 支持rtsp、http的摄像头-程序员宅基地

文章浏览阅读1.4k次。LiveNVR配置拉转RTSP传统海康大华安防摄像机直播流输出RTSP/RTMP/HLS/HTTP-FLV如何获取直播流地址1、 Onvif/RTSP流媒体服务2、配置拉转直播流2.1 RTSP获取配置规则2.2 编辑通道配置3、接口获取视频流地址3.1、获取通道直播链接接口3.2、获取HTTP-FLV播放地址示例3.3、获取WS-FLV播放地址示例3.3、获取RTMP播放地址示例3.4、获取HLS播放地址示例3.4、获取RTSP播放地址示例4、浏览器F12查看播放地址5、播放页面快速集成1、 Onvif_公网 支持rtsp、http的摄像头

Python 爬取qqmusic音乐url并批量下载_qq音乐源url怎么下载-程序员宅基地

文章浏览阅读1.7k次,点赞3次,收藏13次。使用Python爬虫批量下载音乐_qq音乐源url怎么下载

推荐文章

热门文章

相关标签