vla*_*don 6 c++ singleton destructor design-patterns
几分钟前我问了一个关于单例实现的问题,我从@LightnessRacesinOrbit得到了非常好的答案.
但是我无法理解为什么在下一个例子中如果我Singleton在变量中实例化inst它的析构函数被调用两次?
#include <iostream>
class Singleton
{
public:
~Singleton() { std::cout << "destruction!\n"; }
static Singleton& getInstance()
{
static Singleton instance;
return instance;
}
void foo() { std::cout << "foo!\n"; }
private:
Singleton() { std::cout << "construction!\n"; }
};
int main()
{
Singleton inst = Singleton::getInstance();
inst.foo();
}
Run Code Online (Sandbox Code Playgroud)
输出:
construction!
foo!
destruction!
destruction!
Run Code Online (Sandbox Code Playgroud)
更正确的是,我理解为什么它会被调用两次.但是,如果在第一个析构函数之后,类的实例被销毁,我无法理解如何调用它两次?为什么没有例外?
还是没有被摧毁?为什么?
Cor*_*mer 17
这条线
Singleton inst = Singleton::getInstance();
Run Code Online (Sandbox Code Playgroud)
应该
Singleton& inst = Singleton::getInstance();
Run Code Online (Sandbox Code Playgroud)
然后你只会看到一个析构函数调用.
它的编写方式Singleton::getInstance()返回一个引用,然后将其复制到inst.因此,Singleton从您的函数返回的内容和副本都将被销毁.你从来没有看到副本被构造,因为没有使用默认构造函数,复制构造函数是.
在第二种方法中,返回引用,然后您只需要inst引用它Singleton而不是复制.
正如其他人所提到的,你可以使这个类不可复制和不可移动以防止这种情况发生
Singleton(Singleton const&) = delete; // Copy construct
Singleton(Singleton&&) = delete; // Move construct
Singleton& operator=(Singleton const&) = delete; // Copy assign
Singleton& operator=(Singleton &&) = delete; // Move assign
Run Code Online (Sandbox Code Playgroud)
这条线
Singleton inst = Singleton::getInstance();
Run Code Online (Sandbox Code Playgroud)
使用自动生成的复制构造函数复制您的实例.为防止这种情况发生,请添加
Singleton( const Singleton& ) = delete;
Run Code Online (Sandbox Code Playgroud)
到你的班级,以防止这些复制品.为了确保捕捉到更加模糊的错误,还要添加
void operator=( const Singleton& ) = delete;
Run Code Online (Sandbox Code Playgroud)
同样.您不必显式删除移动构造或赋值,因为编译器不会在声明其他(已删除)成员的情况下生成它们.