std::make_shared
在创建对象时会调用构造函数,而在单例模式下,构造函数通常是私有的,因此不能直接通过 std::make_shared
来创建对象。
为什么 std::make_shared
不适用于单例模式?
在单例模式中,我们希望确保一个类只有一个实例,并且通常会将构造函数设为私有或删除,以防止外部直接创建对象。例如:
class Singleton {
private:Singleton() = default; // 私有构造函数
public:static std::shared_ptr<Singleton> GetInstance();
};
如果使用 std::make_shared<T>()
,它会尝试直接调用 T
的构造函数,而在单例模式中,构造函数是私有的或被删除的,导致编译错误。例如:
std::shared_ptr<T> instance = std::make_shared<T>(); // 会失败,因为T的构造函数是私有的
为什么 new T
可以工作?
在使用 new T
时,std::shared_ptr<T>(new T)
会先通过 new
操作符分配内存并构造对象。由于 new
是在函数内部执行的,它并不受类的访问控制限制。即使构造函数是私有的,new T
仍然可以创建对象。
实际上,std::shared_ptr<T>(new T)
本质上绕过了构造函数的访问控制,它直接使用 new
操作符来分配内存和构造对象。而 std::make_shared<T>()
会在内部调用构造函数,因此在构造函数是私有的情况下,它无法正常工作。
单例模式的实现:
在单例模式中,我们一般通过 new
来动态创建对象,以便绕过私有构造函数的限制。new T
允许我们通过 std::shared_ptr
来管理对象,并且只创建一个唯一的实例。
因此,正确的做法是继续使用 std::shared_ptr<T>(new T)
,因为 std::make_shared
会尝试直接调用构造函数,这与单例模式的设计(构造函数是私有的)不兼容。
结论:
std::make_shared
需要调用构造函数,而在单例模式下,构造函数通常是私有的,因此不能使用std::make_shared
。new T
可以绕过构造函数的访问限制,因此可以在单例模式中使用它来动态创建唯一实例。