singleton 模式 C++
基本形态
#include <iostream>
#include <string>
class TestSingleton
{
public:
static TestSingleton *create_instance(void)
{
if (instance_ == nullptr) {
instance_ = new TestSingleton();
if (instance_ && instance_->init() < 0) {
std::cerr << "fail to create TestSingleton instance"
<< std::endl;
}
}
return instance_;
}
void destroy(void) {
delete instance_;
}
int print_name(void) {
std::cout << name_ << std::endl;
};
private:
TestSingleton() {
name_ = "TestSpace";
}
~ TestSingleton() { };
int init(void) {
return 1;
}
static TestSingleton *instance_;
std::string name_;
};
TestSingleton *TestSingleton::instance_ = nullptr;
- 私有的静态指针变量,以及public的create_instance()函数
- 私有的构造函数和析构函数(防止唯一实例在其他地方被创建)
(静态成员函数可以访问私有成员,唯一的区别是,静态成员函数没有this指针,只能用对象实例指针来访问私有成员)
工厂方法的基本形态
在上面给出的代码示例中,用到了工厂方法,这里给出工厂方法使用的基本形态。
abstractClass *create_instance(void)
{
concreteClass *instance = nullptr;
instance = new concreteClass();
if (instance && instance->init() < 0) {
std::cerr << "fail to create TestSingleton instance"
<< std::endl;
}
return instance;
}
new 实体类,首先分配内存,然后调用构造函数,构造函数没有返回值导致不能判断所有构造初始化过程是否失败。所以添加一个init函数,这个函数完成除基本赋初值之外的其他初始化过程。
多线程保护
使用shared_ptr 计数
#ifndef _TEST_SHARED_PTR_
#define _TEST_SHARED_PTR_
#include <memory>
#include <mutex>
#include <iostream>
class Singleton
{
public:
static std::shared_ptr<Singleton> create_instance(void);
void destroy_instance(void);
private:
void destroy();
static std::shared_ptr<Singleton> g_singleton;
static std::mutex g_mutex_singleton;
Singleton() { std::cout << "create SingleTon" << std::endl; }
virtual ~Singleton() { std::cout << "destroy SingleTon" << std::endl;}
};
#endif /* _TEST_SHARED_PTR_ */
#include <functional>
#include "test_shared_ptr.h"
std::shared_ptr<Singleton> Singleton::g_singleton;
std::mutex Singleton::g_mutex_singleton;
std::shared_ptr<Singleton> Singleton::create_instance(void)
{
Singleton *test = nullptr;
std::lock_guard<std::mutex> lock(g_mutex_singleton);
if (!g_singleton) {
g_singleton.reset(new Singleton());
}
return g_singleton;
}
void Singleton::destroy_instance(void)
{
std::lock_guard<std::mutex> lock(g_mutex_singleton);
g_singleton.reset();
}
int main(int argc, char *argv[])
{
std::shared_ptr<Singleton> test_singleton;
test_singleton = Singleton::create_instance();
test_singleton->destroy_instance();
return 0;
}
满足构造函数析构函数私有,create_instance, destroy 开放的要求。
shared_ptr 的reset()方法将shared_ptr 清空,ref_count减到0
代替shared_ptr 的方法
#include <string>
#include <atomic>
class SingletonTestInterface {
public:
virtual void print_interface_name(void) = 0;
virtual void destroy(void) = 0;
protected:
virtual ~SingletonTestInterface() {};
};
class SingletonTest : public SingletonTestInterface
{
public:
static SingletonTestInterface *create_instance(void);
virtual void print_interface_name(void) override;
virtual void destroy(void) override;
private:
SingletonTest();
SingletonTest(const SingletonTest &instance) = delete;
SingletonTest &operator= (const SingletonTest &instance) = delete;
~SingletonTest();
int init(void);
int inc_ref(void);
private:
static SingletonTest *g_instance;
private:
std::atomic<int> m_ref_count;
std::string m_name;
};
#endif
#include "singleton.h"
#include <iostream>
SingletonTest *SingletonTest::g_instance = nullptr;
SingletonTestInterface *SingletonTest::create_instance(void)
{
if (!g_instance) {
g_instance = new SingletonTest();
if (!g_instance || g_instance->init() < 0) {
std::cout << "fail to create SingletonTest instance" << std::endl;
if (g_instance) {
g_instance->destroy();
g_instance = nullptr;
}
}
}
if (g_instance) {
g_instance->inc_ref();
}
return (SingletonTestInterface *) g_instance;
}
SingletonTest::SingletonTest()
:m_ref_count(0),
m_name("SingletonTest")
{
}
SingletonTest::~SingletonTest()
{
}
void SingletonTest::destroy(void)
{
if (!(-- m_ref_count)) {
delete this;
}
}
int SingletonTest::inc_ref(void)
{
return ++ m_ref_count;
}
int SingletonTest::init(void)
{
return 0;
}
void SingletonTest::print_interface_name(void)
{
std::cout << "SingletonTest instance" << std::endl;
std::cout << "m_ref_count:" << m_ref_count.load() << std::endl;
}