文章目录
引言
相信大家对单例模式都不陌生,本博客主要结合C++17写一个相对标准的单例模式框架,并进行讲解。
这也是创建型模式的最后一篇,大家感兴趣的可以看看其余4个创建型模式:
单例代码实现
单类简易版
cpp
class Singleton {
public:
// 获取唯一实例的全局访问点(懒加载 + 线程安全)
static Singleton& instance() noexcept {
static Singleton instance; // C++11 起保证线程安全
return instance;
}
// 禁止拷贝和移动
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
Singleton(Singleton&&) = delete;
Singleton& operator=(Singleton&&) = delete;
// 提供示例方法
void doSomething() {
std::cout << "Singleton working at " << this << std::endl;
}
private:
// 构造函数设为私有,防止外部创建
Singleton() {
std::cout << "Singleton constructed.\n";
}
~Singleton() {
std::cout << "Singleton destroyed.\n";
}
};
// 测试
int main() {
Singleton::instance().doSomething();
Singleton::instance().doSomething();
}
模板通用版
cpp
// === 通用单例模板 ===
template <typename T>
class Singleton {
public:
static T& instance() {
static T instance; // C++11+ 确保线程安全
return instance;
}
protected:
Singleton() = default;
~Singleton() = default;
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
};
// === 具体的单例类 ===
class Logger : public Singleton<Logger> {
friend class Singleton<Logger>; // 允许 Singleton 访问私有构造
private:
Logger() = default; // 外部无法 new Logger()
~Logger() = default;
public:
void log(const std::string& message) {
std::cout << "[LOG] " << message << std::endl;
}
};
// === 使用示例 ===
int main() {
// 获取 Logger 的唯一实例
auto& logger = Logger::instance();
// 使用单例对象
logger.log("System initialized.");
logger.log("User logged in.");
// 再次获取 instance,返回同一个对象
auto& logger2 = Logger::instance();
logger2.log("Still the same instance!");
// 验证地址一致
std::cout << "logger addr: " << &logger << std::endl;
std::cout << "logger2 addr: " << &logger2 << std::endl;
return 0;
}