1,singleton 相对于全局数据的优势
使用 Singleton 类相对于全局数据具有以下好处:
1.1. 延迟初始化:Singleton 类可以实现延迟初始化,即在需要时才创建实例,而全局数据在程序启动时就会被初始化。这可以节省资源并提高性能。
1.2. 控制访问:Singleton 类可以提供更好的访问控制,通过提供公共静态方法来访问实例,可以限制对实例的访问方式,避免直接访问全局数据。
1.3. 线程安全:Singleton 类可以实现线程安全的实例化,通过加锁或其他线程安全机制来保证在多线程环境下只创建一个实例,而全局数据可能需要额外的同步机制来保证线程安全。
1.4. 更好的封装:Singleton 类提供了更好的封装性,可以隐藏实例化细节并提供更清晰的接口,而全局数据可能会暴露在整个程序中,导致耦合性增加。
1.5. 易于扩展:Singleton 类可以更容易地扩展和维护,可以在类中添加新的功能和行为,而全局数据可能会导致代码膨胀和难以维护。
总的来说,使用 Singleton 类相对于全局数据可以提供更好的封装、控制访问、线程安全性和延迟初始化等优势,使得代码更加健壮、可维护和可扩展。
2,全局数据相对于singleton的优势
使用全局数据相对于 Singleton 类具有以下一些优势:
2.1. 简单性:全局数据的实现通常比 Singleton 类更简单直接,不需要额外的设计模式和复杂的实现。
2.2. 易于访问:全局数据可以在任何地方直接访问,不需要通过特定的接口或方法来获取实例。
2.3. 更快速的访问:全局数据的访问速度可能会更快,因为不需要额外的方法调用或实例化过程。
2.4. 适用性:在某些情况下,全局数据可能更适合特定的应用场景,例如需要在整个程序中共享的配置信息或状态。
2.5. 少量数据:对于少量数据或简单的应用,全局数据可能是更简单和有效的选择,避免引入不必要的复杂性。
3.结论
尽管全局数据具有一些优势,但在大多数情况下,推荐使用 Singleton 类来管理全局状态和数据,因为 Singleton 类提供了更好的封装、控制访问、线程安全性和延迟初始化等优势,使得代码更加健壮、可维护和可扩展。选择使用全局数据还是 Singleton 类取决于具体的需求和设计考虑。
4,singleton C++ DCL 示例
4.1 示例一
单文件示例
hello_dcl_sing.cpp
#include <iostream>
#include <mutex>
class Singleton {
private:
Singleton() {} // 私有构造函数
static Singleton* instance; // 单例对象指针
static bool inited; // 初始化标志
static std::mutex mtx; // 用于线程同步的互斥锁
//
public:
// 获取单例对象的方法
static Singleton* getInstance() {
if (!inited) { // 第一次检查,无需同步
std::lock_guard<std::mutex> lock(mtx); // 同步块
if (!inited) { // 第二次检查,确保线程安全
instance = new Singleton(); // 安全创建单例对象
inited = true; // 标记已初始化
}
}
return instance; // 返回单例对象
}
// 其他成员函数和方法...
};
Singleton* Singleton::instance = nullptr; // 静态成员初始化
bool Singleton::inited = false; // 初始化标志默认为false
std::mutex Singleton::mtx; // 用于线程同步的互斥锁
int main() {
Singleton* s1 = Singleton::getInstance();
Singleton* s2 = Singleton::getInstance();
if (s1 == s2) {
std::cout << "Singletons are the same instance." << std::endl;
}
return 0;
}
编译运行:
g++ hello_dcl_sing.cpp
./a.out
效果图:
4.2 示例二
双文件示例
源码:
singleton.h
// singleton.h
#ifndef SINGLETON_H
#define SINGLETON_H
#include <iostream>
#include <mutex>
using namespace std;
class Singleton
{
public:
static Singleton* GetInstance();
void print_info();
private:
Singleton(int a, int b, int c) {major = a; minor = b; patch = c;} // construction, private
private:
static Singleton *m_pSingleton; // pointer points self single instance
static mutex m_mutex; // lock for thread-safe
int major;
int minor;
int patch;
};
#endif // SINGLETON_H
singleton.cpp
// singleton.cpp
#include "singleton.h"
Singleton *Singleton::m_pSingleton = NULL;
mutex Singleton::m_mutex;
Singleton *Singleton::GetInstance()
{
if (m_pSingleton == NULL) {
std::lock_guard<std::mutex> lock(m_mutex); // self-unlocking
if (m_pSingleton == NULL) {
m_pSingleton = new Singleton(1, 2, 3);
}
}
return m_pSingleton;
}
void Singleton::print_info()
{
printf(" major = %d\n minor = %d\n patch = %d\n", major, minor, patch);
}
app 源码
ex.cpp
#include "singleton.h"
int main()
{
Singleton::GetInstance()->print_info();
return 0;
}
Makefile
all: ex
%.o: %.cpp
g++ $< -c -o $@
ex: ex.o singleton.o
g++ $^ -o $@
.PHONY: clean
clean:
-rm -rf ex.o ex singleton.o
编译运行: