C++单例模板类,继承及使用
前言:
单例模式可以参考如下文章:
我的设计模式,单例模式的设计和实现
c++ 单例模式的模板类 - 川野散人 - 博客园
1.为什么需要单例模板类?
场景问题:
如果需要100个单例类就需要设计100个单例模式,代码重复且冗余,不利于扩展。
单例模板类可以实现单例模式的基础功能,普通类继承它之后,就拥有单例的特性。
2.单例模板类需要具备哪些特质?如何设计?
单例模板类需要具备哪些特质?
- 单例模板类的构造函数应该是protected的?(子类要拥有创建父类的权限,但是不能是pubic,如果是public就丧失单例特性)
- 单例模板类的析构函数应该是protected的?(子类要拥有析构父类的权限,但是不能是pubic,会重复析构)
- 单例模板不能使用拷贝构造
- 单例模板不能使用拷贝赋值
- 单例模板应提供实例的public方法
设计代码如下:
template<typename T>
class Singleton
{
protected:
Singleton(){std::cout << "Singleton()!" << std::endl;}
~Singleton(){std::cout << "~Singleton()!" << std::endl;}
public:
static T& getInstance()
{
static std::mutex mtx;
static std::unique_ptr<T> uniPtr;
if (uniPtr == nullptr)
{
mtx.lock();
if (uniPtr == nullptr)
{
uniPtr.reset(new T());
}
mtx.unlock();
}
return *uniPtr;
}
private:
Singleton(const Singleton& s) = delete;
Singleton& operator = (const Singleton& s) = delete;
};
继承者应注意哪些?
- 继承者的构造函数应设为私有
- 继承者应设置单例模板类为友元(父类可以调用继承者私有构造函数)
class MySingleton :public Singleton<MySingleton>
{
friend class Singleton<MySingleton>;
private:
MySingleton() {std::cout << "MySingleton()!" << std::endl;}
public:
//unique_ptr需要权限销毁管理的对象
~MySingleton() {std::cout << "~MySingleton()!" << std::endl;}
public:
void MySingletonSay(){std::cout << "MySingletonSay : Hello World!" << std::endl;}
};
3.测试代码
int main()
{
{
MySingleton::getInstance().getInstance().MySingletonSay();
}
{
MySingleton::getInstance().MySingletonSay();
}
}
输出:
Singleton()!
MySingleton()!
MySingletonSay : Hello World!
MySingletonSay : Hello World!
~MySingleton()!
~Singleton()!
4.当我设置继承者析构函数为私有时,编译unique_ptr报错
class MySingleton :public Singleton<MySingleton>
{
friend class Singleton<MySingleton>;
private:
MySingleton() {std::cout << "MySingleton()!" << std::endl;}
~MySingleton() {std::cout << "~MySingleton()!" << std::endl;}
public:
void MySingletonSay(){std::cout << "MySingletonSay : Hello World!" << std::endl;}
};
5.继承者析构函数不显式声明,编译unique_ptr不报错,但析构不完全
class MySingleton :public Singleton<MySingleton>
{
friend class Singleton<MySingleton>;
private:
MySingleton() {std::cout << "MySingleton()!" << std::endl;}
public:
void MySingletonSay(){std::cout << "MySingletonSay : Hello World!" << std::endl;}
};
- 输出
Singleton()!
MySingleton()!
MySingletonSay : Hello World!
MySingletonSay : Hello World!
~Singleton()!
6.继承者析构函数声明为public可能出现的问题举例
#include <iostream>
#include <memory>
#include <mutex>
template<typename T>
class Singleton
{
protected:
Singleton(){std::cout << "Singleton()!" << std::endl;}
~Singleton(){std::cout << "~Singleton()!" << std::endl;}
public:
static T& getInstance()
{
static std::mutex mtx;
static std::unique_ptr<T> uniPtr;
if (uniPtr == nullptr)
{
mtx.lock();
if (uniPtr == nullptr)
{
uniPtr.reset(new T());
}
mtx.unlock();
}
return *uniPtr;
}
private:
Singleton(const Singleton& s) = delete;
Singleton& operator = (const Singleton& s) = delete;
};
class MySingleton :public Singleton<MySingleton>
{
friend class Singleton<MySingleton>;
private:
MySingleton() {std::cout << "MySingleton()!" << std::endl;}
public:
//unique_ptr需要权限销毁管理的对象
~MySingleton() {std::cout << "~MySingleton()!" << std::endl;}
public:
void MySingletonSay(){std::cout << "MySingletonSay : Hello World!" << std::endl;}
};
int main()
{
{
MySingleton::getInstance().MySingletonSay();
delete &MySingleton::getInstance();
}
std::cout << "end...................." << std::endl;
}
- 输出:出现了重复析构sos
Singleton()!
MySingleton()!
MySingletonSay : Hello World!
~MySingleton()!
~Singleton()!
end....................
~MySingleton()!
~Singleton()!