C++中实现singleton(单例模式)的最简单写法

前几天看了 Java中实现singleton的写法,就想在C++中实现一下,找了很多资料,看了各个牛人写的不同版本,但最后在stack overflow上找到了一个最简单的写法,不需要判断是否已经有实例存在,则在多线程的情况也可以正常使用,现在贴出来以供参考:

class S
{
    public:
        static S& getInstance()
        {
            static S    instance; 
            return instance;
        }
    private:
        S() {};                   // Constructor
        S(S const&);              // Don't Implement
        void operator=(S const&); // Don't implement
};
它其实是使用了C++中成员函数的静态变量的特点:静态局部变量在第一次使用时初始化,并不会销毁直到程序退出。

具体资料:http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable-in-a-c-function

下面是我总结的四种singleton在C++中的实现方法:


// Singleton.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <Windows.h>
using namespace std;

//C++ Singleton Version 1
class Singleton1
{
private:
	Singleton1(){};
	static Singleton1* instance;
	virtual ~Singleton1(void){}
public:
	int ia;
	static Singleton1* GetInstance()
	{
		if (NULL == instance)
		{
			instance = new Singleton1();
		}
		return instance;
	}
};
//Must define static member, not just declaration
Singleton1* Singleton1::instance = NULL;

//C++ Singleton Version 2
//Use smart point to release memory
#include <memory>
using namespace std;
class Singleton2
{
public:
	static Singleton2 * GetInstance()
	{
		if (NULL == instance.get())
		{
			instance.reset(new Singleton2());
		}
		return instance.get();
	}
	int ia;
private:
	static shared_ptr<Singleton2> instance;
	
};
shared_ptr<Singleton2> Singleton2::instance;

//C++ Singleton Version 3
//Use template to reduce some duplicate work
template <class T>
class Singleton
{
public:
	static T* GetInstance();
private:
	Singleton(){}
	~Singleton(){}
	Singleton(const Singleton&){}
	Singleton& operator=(const Singleton&){}
	
	static shared_ptr<T> instance;
};

template <class T>
shared_ptr<T> Singleton<T>::instance;

template <class T>
T* Singleton<T>::GetInstance()
{
	if (NULL = instance.get())
	{
		instance.reset(new Singleton());
	}
	return instance.get();
}

//C++ Singleton Version 4
//Avoid memory allocation
class Singleton4
{
public:
	static Singleton4& GetInstance()
	{
		// Guaranteed to be destroyed.
		// Instantiated on first use.
		// Static variable lifetime in function-http://stackoverflow.com/questions/246564/what-is-the-lifetime-of-a-static-variable-in-a-c-function
		static Singleton4 instance;
		return instance;
	}
private:
	Singleton4(){}
	~Singleton4(){}
	// Dont forget to declare these two. You want to make sure they
	// are unaccessable otherwise you may accidently get copies of
	// your singleton appearing.
	Singleton4(Singleton4 const&);//Don't Implement
	void operator=(Singleton4 const&);//Don't Implement
};


int _tmain(int argc, _TCHAR* argv[])
{
	/* version 1: Memory leak
	Singleton1* a = Singleton1::GetInstance();
	a->ia = 100;
	Singleton1* b = Singleton1::GetInstance();
	cout << b->ia << endl;
	*/

	Singleton2* a2 = Singleton2::GetInstance();
	a2->ia = 200;
	Singleton2* b2 = Singleton2::GetInstance();
	cout << b2->ia << endl;
	OutputDebugString(_T("hello world!"));

	system("pause");

	return 0;
}


### C++ 单例模式中不使用 `this` 指针的设计分析 在单例模式中,通常会遇到一些关于 `this` 指针使用的讨论。这是因为单例模式的核心目标之一是确保类仅有一个实例,并提供对该实例的全局访问点。然而,在某些情况下,可能希望避免显式使用 `this` 指针来提高代码可读性和一致性。 #### 解决方案:通过直接操作静态成员替代 `this` 在一个典型的单例实现中,可以通过直接操作静态成员变量和函数的方式,完全避免显式使用 `this` 指针。以下是具体实现: ```cpp class Singleton { public: static Singleton& GetInstance() { if (!_instance) { _instance = new Singleton(); } return *_instance; } void DoSomething() const { std::cout << "Doing something..." << std::endl; } private: Singleton() {} ~Singleton() {} // 删除拷贝构造函数和赋值运算符 Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; static Singleton* _instance; }; // 静态成员初始化 Singleton* Singleton::_instance = nullptr; int main() { Singleton& instance = Singleton::GetInstance(); instance.DoSomething(); return 0; } ``` 在这个例子中,所有的操作都通过静态成员 `_instance` 来完成,而不需要显式的 `this` 指针[^1]。 --- #### 使用局部静态变量简化实现 另一种常见的做法是利用 C++ 的局部静态变量特性,进一步减少对 `this` 指针的依赖。这种方式不仅简洁,而且能够自动管理内存生命周期: ```cpp class Singleton { public: static Singleton& GetInstance() { static Singleton instance; // 局部静态变量,线程安全 (C++11及以上) return instance; } void DoSomething() const { std::cout << "Doing something..." << std::endl; } private: Singleton() {} ~Singleton() {} // 删除拷贝构造函数和赋值运算符 Singleton(const Singleton&) = delete; Singleton& operator=(const Singleton&) = delete; }; int main() { Singleton::GetInstance().DoSomething(); return 0; } ``` 在这种实现中,由于 `static Singleton instance` 是局部静态变量,其生存期贯穿整个程序运行期间,因此无需手动管理内存分配或释放。同时,这种写法也隐去了对 `this` 指针的操作[^2]。 --- #### 设计问题与注意事项 尽管可以避免显式使用 `this` 指针,但在实际开发过程中需要注意以下几点: 1. **线程安全性** 如果使用动态分配的方式来创建单例实例,则需要考虑多线程环境下的同步问题。现代 C++ 提供了更简单的解决方案(如上文提到的局部静态变量),这些方法天然具备线程安全性[^3]。 2. **资源泄漏风险** 动态分配的单例对象可能会导致资源泄漏。如果确实需要动态分配,建议配合智能指针或其他机制进行管理。 3. **单一职责原则** 单例模式虽然提供了便利的全局访问接口,但也容易违背单一职责原则。应谨慎评估是否真的需要将某种功能封装成单例形式。 --- ### 总结 通过合理设计,可以在单例模式中避免显式使用 `this` 指针。主要思路包括直接操作静态成员以及采用局部静态变量等方式。每种方法都有各自的优缺点,需根据实际情况选择最合适的实现策略。 ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值