最近在开发中,使用多个QSharedPointer创建智能指针指向c++11 写的单例时,出现了程序崩溃,如标题的错误提示,故此记录:
错误代码:
QSharedPointer <Singleton>m_test(Singleton.getInstance());
QSharedPointer <Singleton>m_test1(Singleton.getInstance());
QSharedPointer <Singleton>m_test2(Singleton.getInstance());class Singleton
{
private:Singleton() { };~Singleton() { };Singleton(const Singleton&);Singleton& operator=(const Singleton&);
public:static Singleton& getInstance() {static Singleton instance;return instance;}
};
在Qt中,`QSharedPointer` 是一个智能指针,它可以确保当不再有任何`QSharedPointer`指向一个对象时,该对象会被自动删除。使用`QSharedPointer`管理对象的生命周期通常是防止内存泄漏的好方法。然而,如果使用`QSharedPointer`指向一个静态单例对象,可能会出现问题,原因如下:
1. 单例模式通常意味着对象在第一次创建时就存在,并在程序结束时才销毁。如果用`QSharedPointer`来管理单例对象,那么当最后一个`QSharedPointer`被销毁时,单例对象也会被销毁。这可能与单例的预期生命周期冲突。
2. 这点就是我这里的错误原因: 如果单例被设计为在程序结束时通过其自己的逻辑来销毁,但在此之前所有的`QSharedPointer`都已经销毁并删除了该对象,那么当单例的析构逻辑再次尝试删除这个对象时,就会发生多重删除。这是因为`QSharedPointer`会在引用计数为零时删除其指向的对象,而单例的析构逻辑可能并不知道对象已经被删除。
3. C++没有定义静态对象析构的顺序。如果`QSharedPointer`是一个静态对象或者全局对象,它可能在其他静态或全局对象之前被销毁,而这些对象可能还需要访问单例。这种情况下,当其他对象尝试访问这个已经被销毁的单例时,程序就会崩溃。
为了避免这种情况,通常单例模式下不应该使用`QSharedPointer`,单例应该自己管理自己的生命周期。