-
2020-02-05 14:46:57
所有单例模类直接继承此模板即可,线程安全,效率高(无锁),延时构造。
#include <iostream> using namespace std; template <typename T> class Singleton { public: //外部获取单例的接口 static T& getInstance() { static Token token; static T instance(token); //函数静态变量可以实现延时构造。 return instance; } //禁止拷贝 Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; protected: //只有子类才能获取令牌。 struct Token{}; //构造和析构函数私有化 Singleton() = default; virtual ~Singleton() = default; }; //具体单例模式 class Single : public Singleton<Single> { public: //Token保证,父类需要调用,其他人无法调用。 Single(Token token) { cout << "construct: " << this << endl; //做你想做的事情。 } ~Single() = default; //禁止拷贝 Single(const Single&) = delete; Single& operator=(const Single&) = delete; }; int main() { cout << "main begin" << endl; Single &s1 = Single::getInstance(); Single &s2 = Single::getInstance(); cout << boolalpha << (&s1 == &s2) << endl; cout << "main end" << endl; return 0; }
更多相关内容 -
c++单例模式类模板的实现
2017-08-20 18:37:49设计模式中的单例模式有懒汉单例模式和饿汉单例模式两种,这部分内容记录在http://blog.csdn.net/qq_29344757/article/details/75575217中。 懒汉单例模式的设计步骤为: (1) 将构造函数的访问属性设置为private,...设计模式中的单例模式有懒汉单例模式和饿汉单例模式两种,这部分内容记录在http://blog.csdn.net/qq_29344757/article/details/75575217中。
懒汉单例模式的设计步骤为:
(1) 将构造函数的访问属性设置为private,不让该类中外部生成对象
(2) 将标志指针变量初始化为NULL
(3) 当外部需要使用对象时,调用类的静态成员函数,该函数判断:
若标志指针变量为NULL,则动态生成对象,并且将该对象的地址赋值给标志指针变量,最后返回该对象的地址;
若标志指针变量不为NULL,即其值等于前面生成的对象的地址,那么直接返回该标志指针
(正是因为这个判断操作,使得懒人单例模式是一种非线程安全的设计模式)饿汉单例模式的设计步骤为:
(1) 将构造函数的访问属性设置为private,不让该类中外部生成对象
(2) 将标志指针变量初始化为动态生成的对象的地址
(3) 当外部需要使用对象时,调用类的静态成员函数,该函数直接返回标志指针不论是二者中的哪一种,我们要将设计的类赋予单例模式属性时,都需要定义静态成员指针变量p和静态成员函数instance()以获得该类唯一对象的地址,这一部分可以提取出来,作为一个单例类模板:
1. 饿汉单例类模板
//singleton_class.h #ifndef __SINGLETON_CLASS_H__ #define __SINGLETON_CLASS_H__ #include <stdio.h> #include <iostream> template <typename T> class singleton { private: static T* p; //标志指针 public: static T* instance(); //得到类型为T对象的方法 }; template <typename T> T* singleton<T>::p = new T(); //不管外部是否要使用对象,进入main函数前就生成T对象,p指向该对象的地址 template <typename T> T* singleton<T>::instance() { return p; } #endif /* __SINGLETON_CLASS_H__ */
2. 懒汉单例模板类
#ifndef __SINGLETON_CLASS_H__ #define __SINGLETON_CLASS_H__ #include <stdio.h> #include <iostream> template <typename T> class singleton { private: static T* p; public: static T* instance(); }; template <typename T> T* singleton<T>::p = NULL; //初始化为NULL,等到外部需要到T类型类对象时再生成对象 template <typename T> T* singleton<T>::instance() { if (NULL == p) p = new T(); return p; } #endif /* __SIGLETON_CLASS_H__ */
上面两种方式的单例模板类测试一样:
#include "singleton_class.h" class TestCls { private: TestCls(){} //私有化构造函数,使本类不能再外部生成对象 TestCls(const TestCls& ); //私有化拷贝构造函数,使本类不能为其它本类对象初始化 TestCls& operator= (const TestCls& ); //私有化赋值操作符,使本类不能为其它本类对象赋值 friend class singleton<TestCls>; //singleton模板类为本类的友缘类,它才能new对象 public: void print_this() { printf("this = %p\n", this); } }; int main(void) { TestCls* s = singleton<TestCls>::instance(); s->print_this(); TestCls* s1 = singleton<TestCls>::instance(); s1->print_this(); return 0; }
编译运行:
-
c++中的单例类模板的实现方法详解
2021-01-20 01:38:46也就是说,显示器、扫描枪、收款箱这三部分都应该有各自的类,并且每个类只能唯一地实例化一个对象,基于这种模式的程序设计,称为单例模式。 !!!单例模式只能创建一个对象,且该对象的生命周期伴随系统的整个... -
C++单例模式模板 (简单易懂且有效)
2021-09-28 16:26:59项目中多次使用单例模式后发现每次都是重复的构建单例类,于是做了一个单例模式的模板。 //单例模板 //delete 与 default 来自于 c++ 11 template <typename T> class Singleton { //使用默认构造和析构函数 ...单例模式几乎是最常用的设计模式,简单易懂,使用起来效果显著,在此也不对单例模式做剖析,不了解的可以自行查阅资料。
项目中多次使用单例模式后发现每次都是重复的构建单例类,于是做了一个单例模式的模板。//单例模板 //delete 与 default 来自于 c++ 11 template <typename T> class Singleton { //使用默认构造和析构函数 Singleton() = default; ~Singleton() = default; public: //删除默认的移动、拷贝、赋值、取址 Singleton(T &&) = delete; Singleton(const T &) = delete; void operator = (const T &) = delete; T *operator &() = delete; //获取实例,对此处有异议也可自行查阅资料 static T* instance() { static T object; return &object; } };
使用示例:
//测试类 class Test { int id; public: void setId(int id) { this->id = id; } int getId() const { return this->id; } }; int main() { Singleton<Test>::instance()->setId(5); std::cout << Singleton<Test>::instance()->getId() << std::endl; }
如果使用的时候觉得调用太长,可以将其 #define 一下,如:
#define SingletonTest Singleton<Test>::instance()
使用时短小很多,减少自己手指的损耗,如下:
int main() { SingletonTest->setId(5); std::cout << SingletonTest->getId() << std::endl; }
宏定义本身是c/c++程序设计中不推荐的做法,关于宏定义是预处理期展开在此也不做赘述,个中利害还需自己斟酌。
到这里你可能会提出质疑,我们在此处并没有做到禁止创建 Test 用户类的对象,如果你有这样的需求,那请往下看.
为了禁止擅自创建 Test(用户类对象),我们改变下策略:
放开模板限制
在此不再删除取址操作(会影响返回对象的引用),取消模板类构造函数的私有化,作为基类,析构函数标记为virtual;template <typename T> class Singleton { public: Singleton() = default; virtual ~Singleton() = default; Singleton(T &&) = delete; Singleton(const T &) = delete; void operator = (const T &) = delete; static T* instance() { static T object; return &object; } };
用户类继承单例模板
与之前不同的是,将创建对象的限制放在了用户类(即将构造函数设置为私有),构造函数私有化后,单例模板也无法创建对象,于是,将单例模板作为友元类;class Test : public Singleton<Test> { int id; Test() = default; public: //单例模板作为友元类 friend class Singleton; void setId(int id) { this->id = id; } int getId() const { return this->id; } };
示例:
int main() { //Test t; //错误,禁止创建对象 Test::instance()->setId(5); std::cout << Test::instance()->getId(); }
目前想到的方法就是这样,如有更好的的方法,还请留下宝贵的意见。
-
C++单例类模板详解
2020-08-26 04:56:09主要介绍了C++单例类模板,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
C++单例模式以及C++单例类模板
2021-06-24 11:14:18C++单例模式以及C++单例类模板 在单例类里,又分为了懒汉式和饿汉式,它们的区别在于创建实例的时间不同: 懒汉式 : 指代码运行后,实例并不存在,只有当需要时,才去创建实例(适用于单线程) 饿汉式 : 指代码一运行,实例...C++单例模式以及C++单例类模板
在单例类里,又分为了懒汉式和饿汉式,它们的区别在于创建实例的时间不同:
懒汉式 : 指代码运行后,实例并不存在,只有当需要时,才去创建实例(适用于单线程)
饿汉式 : 指代码一运行,实例已经存在,当时需要时,直接去调用即可(适用于多线程)用法
将构造函数的访问属性设置为private,
提供一个GetInstance()静态成员函数,只能供用户访问唯一一个实例.
定义一个静态成员指针,用来供用户获取
重载 (=)赋值操作符以及拷贝构造函数,并设为private, 避免对象间拷贝,复制.
简单单例类-懒汉式:class CSingleton { private: static CSingleton* m_pInstance; CSingleton() //构造函数为private { } CSingleton& operator = (const CSingleton& t); CSingleton(const CSingleton &); public: static CSingleton* getInstance() { if(m_pInstance==NULL) m_pInstance= new CSingleton(); return m_pInstance; } void print() { cout<<this<<endl; } }; CSingleton* CSingleton::m_pInstance = NULL; int main() { CSingleton *p1=CSingleton::getInstance(); CSingleton *p2=CSingleton::getInstance(); CSingleton *p3=CSingleton::getInstance(); p1->print(); p2->print(); p3->print(); return 0; }
打印结果
0x6e2d18 0x6e2d18 0x6e2d18
从打印结果可以看出,该指针对象指向的都是同一个地址,实现了一个类最多只能有一个实例(instance)存在.
**注意:**由于实例(instance),在系统生命期中,都是存在的,所以只要系统还在运行,就不需要delete
上面的懒汉式如果在多线程情况下 ,多个Csingleton指针对象同时调用getInstance()成员函数时,由于m_pInstance = NULL,就会创建多个实例出来.
所以,在多线程情况下,需要使用饿汉实现
class CSingleton { private: static CSingleton* m_pInstance; CSingleton() //构造函数为private { } CSingleton& operator = (const CSingleton& t); CSingleton(const CSingleton &); public: static CSingleton* getInstance() { return m_pInstance; } }; CSingleton* CSingleton::m_pInstance = new CSingleton;
单例类模板
单例类模板,使用时候可以友元使用,可以继承使用。
注意
优先使用组合而非继承
/************************************************************************/ /* 名称:单例模板类 /* 说明:可把任何类包装成线程安全的全局单例类, 利用了C++11的智能指针和自解锁等 并实现自动GC。 */ /************************************************************************/ #include <mutex> #include <memory> template<typename T> class CSingleton { public: //获取全局单例对象 template<typename ...Args> static std::shared_ptr<T> GetInstance(Args&&... args) { if (!m_pSington) { std::lock_guard<std::mutex> gLock(m_Mutex); if (nullptr == m_pSington) { m_pSington = std::make_shared<T>(std::forward<Args>(args)...); } } return m_pSington; } //主动析构单例对象(一般不需要主动析构,除非特殊需求) static void DesInstance() { if (m_pSington) { m_pSington.reset(); m_pSington = nullptr; } } private: explicit CSingleton (); CSingleton (const CSingleton &) = delete; CSingleton & operator=(const CSingleton &) = delete; ~CSingleton (); private: static std::shared_ptr<T> m_pSington; static std::mutex m_Mutex; }; template<typename T> std::shared_ptr<T> CSingleton<T>::m_pSington = nullptr; template<typename T> std::mutex CSingleton<T>::m_Mutex; #endif
使用
using namespace std; class Test{ public: Test(const string& strData) : m_strData(strData) { cout << m_strData.data() << endl; }; ~Test() { cout << "destory" << endl; }; private: string m_strData; }; auto main()->int { //等同于入口函数int main() auto pTest = CSingleton <Test>::GetInstance("create"); CSingleton <Test>::DesInstance(); return 1; }
#pragma once #include <QtCore/QCoreApplication> #include <QtCore/QAtomicPointer> #include <QtCore/QReadWriteLock> #include <QtCore/QMutex> #include <QtCore/QDebug> template<class T> class JSingleton { public: static T& getInstance(void); //获取唯一实例 private: JSingleton(); //禁止外部构造函数 JSingleton(const JSingleton<T> &); //禁止外部拷贝构造函数 JSingleton<T>& operator = (const JSingleton<T>&); //禁止外部赋值拷贝函数 ~JSingleton(); //禁止外部析构函数 QReadWriteLock m_internalMutex; //函数使用的读写锁 static QMutex m_mutex; //实例互斥锁 static QAtomicPointer<T> m_instance; //实例 }; //静态成员变量初始化 template<class T> QMutex JSingleton<T>::m_mutex(QMutex::Recursive); //一个线程可以多次锁同一个互斥量 template<class T> QAtomicPointer<T>JSingleton<T>::m_instance; //原子指针,默认初始化为0 template<typename T> T& JSingleton<T>::getInstance(void) { #ifdef Q_ATOMIC_POINTER_TEST_AND_SET_IS_ALWAYS_NATIVE if(!QAtomicPointer<T>::isTestAndSetNative()) //运行时检测 qDebug() << QStringLiteral("Error: don's support TestAndSetNative!!!"); #endif //双重检测加锁 /* ! testAndSetOrders 操作保证在原子操作前和后的的内存访问 * 不会被重新排序。 */ if(m_instance.testAndSetOrdered(0, 0)) //第一次检测 { QMutexLocker locker(&m_mutex); //加锁 m_instance.testAndSetOrdered(0, new T); //第二次检测 } return *m_instance/*.load()*/; } //调用示例: 如对于class JTest() //typedef JSingleton<JTest> test; //使用JTest来实例化模板 //test::getInstance().fxxx();
-
C++单例模式与单例类模板
2021-05-13 09:40:331、单例模式(1)需求的提出:在架构设计时,某些类在整个系统生命周期中最多只能有一个对象存在(Single,Instance)(2)问题:如何定义一个类,使得这个类最多只能创建一个对象?要控制类的对象数目,必须对外隐藏构造... -
如何在 C++ 中实现一个单例类模板
2020-12-16 21:50:32在实际工程中,如果一个类的对象重复持有资源的成本很高,且对外接口是线程安全的,我们往往倾向于将其以单例模式管理。 此篇我们在 C++ 中实现正确的单例模式。 选型 在 C++ 中,单例模式有两种方案可选。 一是... -
C++ 单例类模板(详解)
2020-12-15 08:53:28@C+± 单例类模板(详解) 系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考... -
C++之单例类模板
2020-10-08 15:17:08在架构设计时,某些类在整个系统生命周期中最多只能有一个对象存在(Single Instance) 要控制类的对象数目,必须对外隐藏构造函数; 思路: 1、将构造函数的访问属性设置为private 2、定义instance并初始化为NULL... -
C++单例模式的几种实现
2022-03-20 16:47:21本文介绍C++单例模式的集中实现方式,以及利弊 局部静态变量方式 //通过静态成员变量实现单例 //懒汉式 class Single2 { private: Single2() { } Single2(const Single2 &) = delete; Single2 &... -
C++单例模式实现
2022-02-27 15:36:59一、单例模式 1.1 基本概念 单例 Singleton 是设计模式的一种,其特点是只提供唯一一个类的实例,具有全局变量的特点,在任何位置都可以通过接口获取到那个唯一实例; 保证一个类仅有一个实例; 并提供一个访问它... -
C++ 单例模式(饿汉模式、懒汉模式)
2021-06-16 20:18:39文章目录前言一、单例模式的应用场景二、单例...一个类只能创建一个对象,让类自身负责保存它的唯一实例,并提供一个访问它的全局访问接口,这就是单例模式。 Singleton类 单例模式 -instance 私有 -Singe -
谈谈 C++ 单例模式
2021-10-25 00:57:45单例模式是一个很常见的设计模式,也广泛应用于程序开发。其具有如下特点:一个类只有一个实例化对象全局可以使用那么有人要问,那我不就定义一个类,程序只初始化一个全局的实例就好了吗?没错,这样是... -
C++ 单例模式的模板类 - 懒汉类型
2019-03-30 15:21:041、简单的单例模式类 class singleton{ private: singleton(); ~singleton(); singleton(const singleton&); singleton& operator=(const singleton&); public: static singleton* GetIns... -
C++单例模板类
2019-08-16 00:35:44单例模式是保证一个类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。 本文提供两种方式实现单例模板类:1、使用私有静态指针变量 2、使用局部静态变量, 具体如下: 1、私有静态指针变量 ... -
c++友元模板单例模式
2021-06-30 19:51:081、定义一个单例的模板类,以便于其他类可以继承 template <typename T> struct singleton { static T& Instance(); }; template <typename T> T& singleton<T>::Instance() { static... -
C++设计模式——一个基于C++11的万用单例模板类
2017-11-06 15:41:54单例模式概述单例模式(Singleton),...单例模式的目的很简单,创建一个全局唯一的对象(类or变量)。简单代码实现//Simple_Singleton.hclass Singleton { public: static Singleton* GetInstance() { if (!m_pSin -
QT_C++单例模式懒汉+饿汉.rar
2021-05-26 17:11:05QT_C++单例模式懒汉+饿汉,设计模板,使用QT打开pro文件编译即可,默认控制台输出。 -
C++ 单例模式详解
2020-01-07 15:08:49文章目录C++ 单例模式详解一、单例模式:二、单例的实现思路二、懒汉模式2.0三、最推荐的懒汉模式3.0单例模板的实现:写在最后 C++ 单例模式详解 一、单例模式: 什么是单例:在面向对象编程中,我们创建对象的过程... -
C++单例模式的模板基类
2015-09-04 09:35:52下面用C++实现一个单例模板类,那么其他的类只需继承它,便可以成为单例类。 本例中使用了 CMutex类,是考虑多线程的情况,这个类的定义请参见笔者的另一篇博客《C++简单封装互斥量》, 链接 ... -
C++单例模式详解
2021-01-27 22:22:23一种常用的设计模式,一般指在一个进程中使用单例模式的类只允许存在一个实例化对象, 应用场景: 管理共享资源: 常见于程序配置文件,在整个程序运行期间,使用单例模式的类实例化对象来统一管理配置文件,该... -
C++单例模式
2018-09-17 14:46:42单例模式就是一个类只能被实例化一次 ,更准确的说是只能有一个实例化的对象的类。 创建一个单例模式的类(初想) 一个类只能有一个实例化的对象,那么这个类就要禁止别人new出来,或者通过直接定义一个对象... -
C++ 单例模式(singleton)
2021-06-05 10:00:50所谓单例模式就是让某个类只能产生一个对象。那么在C++语言中该如何设计呢?用static关键字可以实现单例模式,因为static保证同时只有一个对象的产生。下面是单例模式的代码的static实现方式: class single_printer... -
单例模式(C++实现懒汉式)
2021-12-30 19:45:47单例模式是设计模式中的一种,本文记录和总结单例模式的定义以及C++中实现单例模式的几种懒汉式方式。 参考C++ 单例模式总结与剖析 什么是单例模式 单例(Singleton)模式的特点是这个类在全局只有唯一的一个实例... -
单例模式模板类
2021-10-27 15:31:24单例模式模板类 @(C/C++学习笔记) 模板类 #if defined(__SUPPORT_TS_ANNOTATION__) || defined(__clang__) #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) #else #define THREAD_ANNOTATION_...