C++ 智能指针的种类:
std::unique_ptr:确保一个资源(如动态分配的内存)只有一个所有者。当 std::unique_ptr 的实例被销毁时,它所拥有的资源会被自动释放。
std::shared_ptr:通过引用计数机制管理资源。资源会在最后一个引用它的 std::shared_ptr 被销毁时自动释放。
std::weak_ptr:是一种不控制对象生命周期的智能指针,它指向由 std::shared_ptr 管理的资源。std::weak_ptr 可以解决 std::shared_ptr 相互引用导致的循环引用问题。
在 C++ 中,单例模式是一种常用的软件设计模式,它确保一个类只有一个实例,并提供一个全局访问点。使用智能指针来实现单例模式可以很好地管理该实例的生命周期,避免内存泄漏等问题。
下面是一个使用 std::shared_ptr
和线程安全的方式来实现单例模式的示例:
#include <iostream>
#include <memory>
#include <mutex>
class Singleton {
private:
static std::weak_ptr<Singleton> instance; // 弱引用指针
int data; // 模拟数据
// 私有构造函数,防止外部通过new来创建对象
Singleton() : data(0) {}
public:
// 删除拷贝构造函数和拷贝赋值操作符,防止复制和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
// 提供一个全局访问点
static std::shared_ptr<Singleton> getInstance() {
std::lock_guard<std::mutex> lock(mutex_); // 锁定以保证线程安全
if (instance.expired()) { // 检查实例是否有效
instance = std::make_shared<Singleton>(); // 创建实例
}
return instance.lock(); // 返回共享指针
}
// 示例操作
void doSomething() {
std::cout << "Doing something with data: " << data << std::endl;
}
private:
static std::mutex mutex_; // 互斥锁,用于线程安全的实例化
};
// 初始化互斥锁和弱引用指针
std::mutex Singleton::mutex_{};
std::weak_ptr<Singleton> Singleton::instance{};
int main() {
auto singletonInstance = Singleton::getInstance();
singletonInstance->doSomething(); // 使用单例对象执行操作
return 0;
}
在这个示例中,我们使用了 std::shared_ptr
来管理单例的生命周期,并且通过 std::weak_ptr
来避免循环引用的问题。std::mutex
确保了 getInstance
方法的线程安全性,即使在多线程环境下也能正确地创建和管理单例实例。
注意,这个实现确保了懒加载和线程安全,即单例实例只会在首次调用 getInstance
方法时创建,并且在任何线程中都是安全的。同时,由于单例类通常不会有动态分配的资源,所以通常不需要析构函数。如果单例类确实管理了一些资源,那么需要提供一个公开的销毁函数来释放这些资源。