将 shared_ptr 与单例一起使用有什么好处
What is the advantage of using shared_ptr with singleton
这里有两个单例,是什么让第一个更可取,因为两者都只会实例化相应 class 的一个实例:
第一个:
class SharedPointerSingleton {
public:
static std::shared_ptr< SharedPointerSingleton> getSingleton(
{
if( s_pSingleton== 0 ) s_pSingleton = std::shared_ptr< SharedPointerSingleton>(new SharedPointerSingleton());
return s_pSingleton;
}
private:
SharedPointerSingleton(){};
static std::shared_ptr< SharedPointerSingleton> s_pSingleton;
};
第二个:
class PointerSingleton {
public:
static PointerSingleton * getSingleton(
{
if( pSingleton== 0 ) pSingleton = new PointerSingleton ());
return pSingleton;
}
private:
PointerSingleton (){};
static PointerSingleton * pSingleton;
};
两种实施方式各有利弊。第一个解决方案有使用 std::shared_ptr
的开销,这在某些情况下可能会很明显。第二种解决方案不会在程序结束时销毁单例对象。虽然内存会在程序生命周期结束时由 OS 释放,但不正确销毁 C++ 对象通常不是一个好习惯。它可能会直接或间接释放未被 OS 清除的资源,例如临时文件、共享内存等,通常的做法是在析构函数中释放资源。
程序结束时第二次泄漏(虽然 OS 应该 清理内存,但你缺少的析构函数调用可能是个问题)。这可能就是为什么有人在顶部添加了一个智能指针。
但是,两个版本都已损坏,容易受到初始化顺序问题的影响。
相反,"proper"产生单例的方法是这样的:
class SharedPointerSingleton
{
SharedPointerSingleton() = default;
public:
static SharedPointerSingleton& getSingleton(
{
static SharedPointerSingleton instance;
return instance;
}
};
这种方法是安全的,没有智能指针或动态分配的开销。现在这个对象在你第一次请求它的时候就被精确地构建了,这要好得多(除非你想要它在main
之前发生......但是你仍然可以在命名空间实例化它如果您愿意,可以通过调用此函数进行范围!)。
这里有两个单例,是什么让第一个更可取,因为两者都只会实例化相应 class 的一个实例:
第一个:
class SharedPointerSingleton {
public:
static std::shared_ptr< SharedPointerSingleton> getSingleton(
{
if( s_pSingleton== 0 ) s_pSingleton = std::shared_ptr< SharedPointerSingleton>(new SharedPointerSingleton());
return s_pSingleton;
}
private:
SharedPointerSingleton(){};
static std::shared_ptr< SharedPointerSingleton> s_pSingleton;
};
第二个:
class PointerSingleton {
public:
static PointerSingleton * getSingleton(
{
if( pSingleton== 0 ) pSingleton = new PointerSingleton ());
return pSingleton;
}
private:
PointerSingleton (){};
static PointerSingleton * pSingleton;
};
两种实施方式各有利弊。第一个解决方案有使用 std::shared_ptr
的开销,这在某些情况下可能会很明显。第二种解决方案不会在程序结束时销毁单例对象。虽然内存会在程序生命周期结束时由 OS 释放,但不正确销毁 C++ 对象通常不是一个好习惯。它可能会直接或间接释放未被 OS 清除的资源,例如临时文件、共享内存等,通常的做法是在析构函数中释放资源。
程序结束时第二次泄漏(虽然 OS 应该 清理内存,但你缺少的析构函数调用可能是个问题)。这可能就是为什么有人在顶部添加了一个智能指针。
但是,两个版本都已损坏,容易受到初始化顺序问题的影响。
相反,"proper"产生单例的方法是这样的:
class SharedPointerSingleton
{
SharedPointerSingleton() = default;
public:
static SharedPointerSingleton& getSingleton(
{
static SharedPointerSingleton instance;
return instance;
}
};
这种方法是安全的,没有智能指针或动态分配的开销。现在这个对象在你第一次请求它的时候就被精确地构建了,这要好得多(除非你想要它在main
之前发生......但是你仍然可以在命名空间实例化它如果您愿意,可以通过调用此函数进行范围!)。