具有智能指针和析构函数的单例类被调用

Tra*_*pas 5 c++ c++11

我想创建一个单例类,这样当所有指向该类的指针都消失时,会调用析构函数。

#include <memory>
#include <iostream>

class MyClass {
public:
    uint8_t str[50]; //some random data
    MyClass() {LOG("constructor Called"); }
    ~MyClass() {LOG("destructor Called");}
    static std::shared_ptr<MyClass> &Get();

private:
    static std::shared_ptr<MyClass> instance;
};

std::shared_ptr<MyClass> MyClass::instance=NULL;


std::shared_ptr<MyClass> &MyClass::Get()
{
    if (instance == NULL)
    {
        instance= std::shared_ptr<MyClass>(new MyClass());
        return instance;
    }
    return instance;
}

int main()
{
    std::shared_ptr<MyClass> &p1 =MyClass::Get();

    printf("We have %" PRIu32, p1.use_count());
    if (1)
    {
        std::shared_ptr<MyClass> &p2 =MyClass::Get();//this should not  
                                                     //  create a new class
        printf("We have %" PRIu32, p1.use_count());  //this should be two...
        printf("We have %" PRIu32, p2.use_count());  //this should be two...
        //when p1 goes out of scope here it should not call destructor
    }
    printf("We have %" PRIu32, p1.use_count());

    //now destructor should be called
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码不起作用,因为静态实例是一个智能指针并且永远不会超出范围,因此永远不会调用析构函数。

我想要做的是首先创建静态实例以返回智能指针的此实例,然后在返回此智能指针的副本后每次调用。

UKM*_*key 3

std::weak_ptr 就是您正在寻找的。

通过将实例更改为weak_ptr,它不算是共享指针的所有者;这意味着一旦所有其他引用被释放,该对象就会被销毁。也就是说,它确实使您的“Get”函数变得更加复杂,因为您必须尝试从weak ptr获取shared_ptr,然后在成功时返回它,或者在失败时创建一个新的,重新分配实例给它ptr 和返回。

您可以在这里找到更多信息

作为单独的说明,静态成员的析构函数将被调用,只是不会在 main 返回之前调用。大多数人接受静态的这一功能,因为一旦 main 返回,只要应用程序不崩溃,他们并不真正关心会发生什么(尽管使用其他静态的静态往往会导致这种情况)