使用C++模板实现的一种单例工厂

本文介绍了一种使用模板方法实现的单例工厂模式,通过该模式可以避免为每个单例类重复编写getInstance方法。示例中提供了单例工厂的C++实现,并通过TestClass类展示了如何获取单例对象。

最近经常使用单例模式,因此就顺手写了一个单例工厂,从而避免了每个单例类都实现一遍getInstance的方法,不当之处请大家多多指教

//============================================================================
// Name        : InstanceFactory.cpp
// Author      : jeky_zhao
//============================================================================
#include <iostream>
#include <map>
#include <pthread.h>
using namespace std;

static map<string, void*> instanceHolder;
class InstanceFactory {
public:
	template<typename T>
	static T* getInstance() {
		static pthread_mutex_t mutext = PTHREAD_MUTEX_INITIALIZER;
		pthread_mutex_lock(&mutext);
		T* instance = NULL;
		string className = typeid(T).name();
		map<string, void*>::iterator itFind = instanceHolder.find(className);
		if (itFind == instanceHolder.end()) {
			instance = new T();
			instanceHolder.insert(make_pair(className, (void*) instance));
		} else {
			instance = static_cast<T*>(itFind->second);
		}
		pthread_mutex_unlock(&mutext);
		return instance;
	}
};

class TestClass {
public:
	string getName() {return "Jeky_zhao";}
};
int main() {
	TestClass* test1 = InstanceFactory::getInstance<TestClass>();
	TestClass* test2 = InstanceFactory::getInstance<TestClass>();
	printf("Test1 point to:%p,Name:%s\n", test1, test1->getName().c_str());
	printf("Test2 point to:%p,Name:%s\n", test2, test2->getName().c_str());
}





<think>我们将在抽象工厂模式的基础上,将工厂实现模式确保一个类只有一个实,并提供一个全局访问点。 在C++实现需要注意: 1. 构造函数私有化 2. 禁止拷贝构造和赋值 3. 提供静态方法获取实 4. 考虑线程安全(C++11及以后可以使用局部静态变量实现线程安全) 下面以之前的WindowsFactory和MacOSFactory为,将它们改造为。 注意:由于抽象工厂是接口,我们只能将具体工厂实现。 步骤: 1. 将具体工厂的构造函数私有化。 2. 删除拷贝构造函数和赋值运算符。 3. 提供一个静态方法(如getInstance)来获取唯一的实。 4. 在getInstance中使用局部静态变量(C++11保证线程安全)或使用双重检查锁定(但C++11后局部静态变量更简洁安全)。 我们将修改WindowsFactory和MacOSFactory,使它们成为。 修改后的代码示:</think>### C++实现工厂化 在抽象工厂模式中实现化可以确保整个应用中只有一个工厂,特别适合资源密集型或需要全局唯一访问点的场景。以下是三种实现方式: #### 1. 静态局部变量实现C++11 线程安全) ```cpp class WindowsFactory : public GUIFactory { private: WindowsFactory() = default; // 私有构造函数 public: // 删除拷贝和赋值 WindowsFactory(const WindowsFactory&) = delete; void operator=(const WindowsFactory&) = delete; // 获取 static WindowsFactory& getInstance() { static WindowsFactory instance; // C++11 保证线程安全 return instance; } std::unique_ptr<Button> createButton() override { return std::make_unique<WindowsButton>(); } std::unique_ptr<Checkbox> createCheckbox() override { return std::make_unique<WindowsCheckbox>(); } }; // 使用 auto& factory = WindowsFactory::getInstance(); auto button = factory.createButton(); ``` #### 2. 双重检查锁定模式(适用于 C++11 之前) ```cpp #include <mutex> class MacOSFactory : public GUIFactory { private: static MacOSFactory* instance; static std::mutex mtx; MacOSFactory() = default; public: static MacOSFactory* getInstance() { if (!instance) { // 第一次检查 std::lock_guard<std::mutex> lock(mtx); if (!instance) { // 第二次检查 instance = new MacOSFactory(); } } return instance; } // ... 其他成员函数 }; // 静态成员初始化 MacOSFactory* MacOSFactory::instance = nullptr; std::mutex MacOSFactory::mtx; // 使用 auto* factory = MacOSFactory::getInstance(); auto checkbox = factory->createCheckbox(); ``` #### 3. 模板(通用解决方案) ```cpp template <typename T> class Singleton { protected: Singleton() = default; public: Singleton(const Singleton&) = delete; void operator=(const Singleton&) = delete; static T& getInstance() { static T instance; return instance; } }; // 工厂实现 class LinuxFactory : public GUIFactory, public Singleton<LinuxFactory> { friend class Singleton<LinuxFactory>; // 允许访问构造函数 public: std::unique_ptr<Button> createButton() override { return std::make_unique<LinuxButton>(); } std::unique_ptr<Checkbox> createCheckbox() override { return std::make_unique<LinuxCheckbox>(); } private: LinuxFactory() = default; // 私有构造函数 }; // 使用 auto& factory = LinuxFactory::getInstance(); ``` ### 关键实现要点 1. **构造函数私有化**: ```cpp private: MyFactory() = default; // 阻止外部实化 ``` 2. **禁止拷贝和赋值**: ```cpp MyFactory(const MyFactory&) = delete; void operator=(const MyFactory&) = delete; ``` 3. **线程安全访问**: - C++11 及以上:使用静态局部变量(编译器保证线程安全) - 旧标准:双重检查锁定 + 互斥锁 4. **全局访问点**: ```cpp static MyFactory& getInstance() { // 返回引用 } ``` ### 使用场景示 ```cpp // 客户端代码 void createUI() { // 获取工厂 auto& winFactory = WindowsFactory::getInstance(); auto& macFactory = MacOSFactory::getInstance(); // 使用工厂创建产品 auto winButton = winFactory.createButton(); auto macCheckbox = macFactory.createCheckbox(); winButton->render(); macCheckbox->render(); } // 测试性 void testSingleton() { auto& f1 = WindowsFactory::getInstance(); auto& f2 = WindowsFactory::getInstance(); // 地址相同,证明是同一个实 std::cout << "Addresses equal: " << (&f1 == &f2) << std::endl; // 输出 1 (true) } ``` ### 各方案对比 | 方案 | 线程安全 | 内存管理 | 适用标准 | 实现复杂度 | |--------------------|----------|----------------|----------|------------| | 静态局部变量 | ✅ | 自动 | C++11+ | ⭐ | | 双重检查锁定 | ✅ | 需手动释放 | C++98+ | ⭐⭐⭐ | | 模板 | ✅ | 自动 | C++11+ | ⭐⭐ | > **最佳实践**:在 C++11 及以上环境中,优先使用静态局部变量方案,简洁安全。需要兼容旧标准时使用双重检查锁定。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值