Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/154.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 静态唯一性_ptr调用析构函数两次_C++_C++11_Singleton_Lazy Loading_Unique Ptr - Fatal编程技术网

C++ 静态唯一性_ptr调用析构函数两次

C++ 静态唯一性_ptr调用析构函数两次,c++,c++11,singleton,lazy-loading,unique-ptr,C++,C++11,Singleton,Lazy Loading,Unique Ptr,我使用一个单例模式,它返回对unique_ptr dereference的引用。这是密码 #include <iostream> #include <memory> using std::cout; using std::endl; using std::unique_ptr; namespace Settings { class Lazy { Lazy() { cout << "Lazy::Lazy() " << thi

我使用一个单例模式,它返回对unique_ptr dereference的引用。这是密码

#include <iostream>
#include <memory>
using std::cout; using std::endl;
using std::unique_ptr;

namespace Settings {
    class Lazy {
        Lazy() { cout << "Lazy::Lazy() " << this << endl; }
    public:
        ~Lazy() { cout << "Lazy::~Lazy() " << this << endl; }
        static Lazy &instance()
        {
            static unique_ptr<Lazy> lazy(new Lazy);
            return *lazy;
        }
    };

    Lazy &lazy()
    { return Lazy::instance(); }
}

int main()
{
    cout << "main starts!" << endl;
    auto state = Settings::lazy();
    cout << "auto state = Settings::lazy() " << &state << endl;

    cout << "main ends!" << endl;
    return 0;
}

为什么析构函数调用了两次?甚至第二次调用这个地址也是不同的。

因为您有两个单例实例,并且都会被销毁


您必须使用2个单例的原因是,当您获得单例
autostate=Settings::lazy()时创建一个副本。您可能正在返回一个引用,但
state
不是引用,因此创建了一个副本


state
作为引用修复了问题:
auto&state=Settings::lazy()

Rakete1111解决方案是正确的,但您可能还希望删除单例的复制构造函数和复制分配。这样就可以防止此类错误的发生。

单例类必须禁用任何复制/移动构造函数和赋值/移动运算符。 否则,这不是一个单例。
因此,

则以下操作将是唯一有效的操作:

auto& state = Settings::lazy();

auto state=Settings::lazy()调用内部没有任何跟踪输出的自动复制构造函数。如果你真的想要一个单例,你会看到错误。为什么要使用
唯一的\u ptr
?最好是有一个静态对象。我建议看看这个答案:另外,你应该在所有包含之后使用
声明,因为你要使声明之后的头文件可以看到这些符号。不,在函数中,只有在第一次调用该函数时,才会构造静态函数。此外,静态对象的构造保证在第一次调用时是线程安全的(而静态对象的构造是线程安全的)。另请参见使用
auto
Lazy(Lazy &) = delete;
Lazy(Lazy &&) = delete;
Lazy &operator=(Lazy &) = delete;
Lazy &operator=(Lazy &&) = delete;
auto& state = Settings::lazy();