【问题标题】:Correct way to implement singleton with shared pointer?使用共享指针实现单例的正确方法?
【发布时间】:2021-02-15 01:24:48
【问题描述】:

我正在尝试我的第一个更大的 C++ 对象,但在使用共享指针实现单例时遇到了一些问题。

当我尝试编译以下内容时,Visual Studio 给了我这个错误:

“错误 C2248 'PaletteManager::PaletteManager': 无法访问私有 在类“PaletteManager”中声明的成员 {省略}\xmemory 第 228 行“

我猜这个问题是因为我有一个私有构造函数/析构函数,而 make_shared 正试图调用构造函数。这个访问问题对我来说很有意义,但是如果我想使用共享指针作为访问我的单例对象的方式,我应该怎么做?代码在原始指针上工作得很好,但我想尝试用智能指针以干净的方式做事。

这里是相关代码的头文件:

class PaletteManager
{
private:

    // array representing palette colors
    uint* paletteColors;

    // private constructor/destructor because singleton
    PaletteManager();
    ~PaletteManager();

    // load palette from file TODO: not implemented
    void loadPallette();

    static std::shared_ptr<PaletteManager> instance;

public:

    const uint PALETTE_MAX_COLORS = 4;

    uint getPaletteColor(uint idx);

    // singleton accessor
    static std::shared_ptr<PaletteManager> getInstance();
};

这是 cpp 文件中的问题函数:

std::shared_ptr<PaletteManager> PaletteManager::instance = nullptr;

std::shared_ptr<PaletteManager> PaletteManager::getInstance()
{
    if (!PaletteManager::instance) 
    {
        PaletteManager::instance = std::make_shared<PaletteManager>();
    }

    return PaletteManager::instance;
}

【问题讨论】:

标签: c++ singleton


【解决方案1】:
PaletteManager::instance = std::make_shared<PaletteManager>();

这导致std::make_shared 尝试new 一个PalletteManager 对象,然后从中构造一个std::shared_ptr。这就是std::make_shared 所做的,就是它的工作原理。

这在这里行不通:那是因为PalletteManager 有一个私有构造函数,而C++ 库中的模板std::make_shared 不是friend

您必须在 getInstance 中显式地 new 对象,该类的成员可以使用私有构造函数,然后从指向这个新对象的指针手动构造 std::shared_ptr

TLDR:您不能将std::make_shared 用于具有私有构造函数的对象。 C++ 的规则不允许你这样做。

【讨论】:

    【解决方案2】:

    您可以使用私有构造函数使std::make_unique&lt;&gt;() 成为您的类的友元函数。大概这也适用于std::make_shared&lt;&gt;()? (但我没有测试过。)

    例如,请参阅: How to make std::make_unique a friend of my class

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-30
      相关资源
      最近更新 更多