首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用shared_ptr从单例中生成私有析构函数?

如何使用shared_ptr从单例中生成私有析构函数?
EN

Stack Overflow用户
提问于 2022-07-27 10:08:52
回答 1查看 97关注 0票数 0

我测试了来自C++17的两种类型的单例

第一是unique_ptr第二是shared_ptr

它们必须与私有构造函数和析构函数一起工作,因为没有人可以更改任何实例状态。

我最终成功地编写了unique_ptr版本,但是shrared没有完成。

shared_ptr版本出错

错误是‘Singleton2 2::~Singleton2 2()’在这个上下文中是私有的‘{_p->~_Up();}

我怎样才能让shared_ptr单身?

这是代码

代码语言:javascript
运行
复制
class Singleton1
{
    public:
    static Singleton1& GetInstance() 
    {
        if(!mFlag)
        {
            mFlag = true;
            mSingle = std::make_unique<Singleton1>(Singleton1(1));
        }

        return *mSingle.get();
    }

    private:
    friend std::unique_ptr<Singleton1>::deleter_type;

    Singleton1(int n) 
        : mNum(n)
    {
        std::cout << "this is unique_ptr singleton" << std::endl;   
    }

    ~Singleton1() = default;

    private:
    const int mNum;
    inline static bool mFlag;
    inline static std::unique_ptr<Singleton1> mSingle;
};
代码语言:javascript
运行
复制
class Singleton2
{
    public:
    static Singleton2& GetInstance() 
    {
        if(!mFlag)
        {
            mFlag = true;
            mSingle = std::make_shared<Singleton2>(Singleton2(1));
        }

        return *mSingle.get();
    }

    private:
    Singleton2(int n) 
        : mNum(n)
    {
        std::cout << "this is shared_ptr singleton" << std::endl;   
    }

    ~Singleton2() = default;

    private:
    const int mNum;
    inline static bool mFlag;
    inline static std::shared_ptr<Singleton2> mSingle;
};
代码语言:javascript
运行
复制
int main()
{
    Singleton1& res = Singleton1::GetInstance();
    Singleton2& res = Singleton2::GetInstance();

    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-07-27 10:31:15

您可以使用自定义删除器并使该friend of Singleton2

代码语言:javascript
运行
复制
#include <memory>
#include <iostream>

class Singleton2
{
    struct Deleter {
        void operator()(Singleton2* ptr){ delete ptr;}
    };
    friend Deleter;
    public:
    static Singleton2& GetInstance() 
    {
        if(!mFlag)
        {
            mFlag = true;
            mSingle = std::shared_ptr<Singleton2>(new Singleton2(1),Deleter{});
        }

        return *mSingle.get();
    }

    private:
    Singleton2(int n) 
        : mNum(n)
    {
        std::cout << "this is shared_ptr singleton" << std::endl;   
    }

    ~Singleton2() = default;

    private:
    const int mNum;
    inline static bool mFlag;
    inline static std::shared_ptr<Singleton2> mSingle;
};


int main()
{
    //Singleton1& res = Singleton1::GetInstance();
    Singleton2& res = Singleton2::GetInstance();

    return 0;
}

现场演示

但是,考虑将析构函数公之于众。当指针被包裹起来时,就不会有有人不小心破坏物体的危险。如果他们想故意这么做,他们会找到一种方法,不管析构函数是否是privateprivate并不是一种以各种可能的方式阻止某人访问该函数的方法。相反,这是一种毫不含糊地告知其他人,他们不应该使用这种方法的一种方式。而且,由于您没有将指针传递给调用方,所以当析构函数是公共的时,它们也必须“玩把戏”。

PS:我建议您使用Meyers,其中实例存储为函数本地static变量。它是线程安全的,而您的GetInstance不是。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73136044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档