使用 unique_ptr 的单例对象

新手上路,请多包涵

我有以下 CPP 源代码,用于使用 unique_ptr 创建类的单例对象:

 #include <iostream>
#include <memory>

class A
{

public:
    std::unique_ptr<A> getInstance(int log);
    ~A();

private:
    static bool instanceFlag;
    static std::unique_ptr<A> single;
    A(int log);
    int mLog;
};

bool A::instanceFlag = false;
std::unique_ptr<A> A::single = NULL;

std::unique_ptr<A> A::getInstance(int log)
{
    if(!instanceFlag)
    {
        //single = std::make_unique<A>(log);
        single = std::unique_ptr<A>(new A(log));
        instanceFlag = true;
        return std::move(single);
    }
    else
    {
        return std::move(single);
    }
}

A::A(int log) :
    mLog(log)
{

    std::cout << "Called A cons" << std::flush << std::endl;
}

int main()
{
std::unique_ptr<A> mA = A::getInstance(5);
}

但是当我编译代码时,我得到以下错误:

 $ c++ -std=c++11 try2.cpp
try2.cpp: In function 'int main()':
try2.cpp:45:41: error: cannot call member function 'std::unique_ptr<A> A::getInstance(int)' without object
 std::unique_ptr<A> mA = A::getInstance(5);
                                         ^

但是,我的项目中的代码格式完全相同,但出现错误:

 Source code Line 39: single = std::make_unique<A>(log);

编译错误:

 39:   required from here

single = std::make_unique<A>(log);

error: A(int log)' is private
 A::A(int log) :
  ^

原文由 Programmer 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

首先,静态问题。这个:

 std::unique_ptr<A> getInstance(int log);

是一个实例方法。您需要一个 A 的实例来调用它,但是如果不先调用此方法,就无法获得 A 的实例,所以…

使用实例方法的原因是它们可以访问调用它们的实例。您的方法仅使用以下成员:

 static bool instanceFlag;
static std::unique_ptr<A> single;

其中,由于它们是静态的,因此不需要实例。只需将方法设为静态,您就可以调用它而无需先从某处获得 A


二是逻辑问题。您的 getInstance 方法将 unique_ptr --- 返回到您的单个实例。 unique_ptr 的全部意义在于它是 独一无二 的:只有一个指针拥有并控制一个对象的生命周期。当您返回 unique_ptr 时,您 将单例对象的所有权 从单例类本身转移给调用者。您甚至明确地调用了 move 以明确说明这种情况正在发生。

现在,在调用 getInstance 一次之后,你的单例就完全崩溃了。如果您再次调用 getInstance ,则单身人士认为它有一个实例(因为 instanceFlag ),但 unique_ptr 处于不确定状态。我们唯一可以肯定的是,它 控制 A 的实例。

只需将原始指针(或引用)返回到 A 而不是转移所有权。

原文由 Useless 发布,翻译遵循 CC BY-SA 3.0 许可协议

问题是,正如错误日志所示,您正在调用 member functiongetInstance 没有任何实例。函数 std::unique_ptr<A> getInstance(int log); 应声明为 static

声明它 static 如下:

 static std::unique_ptr<A> getInstance(int log);

注意:单例模式getInstance 函数始终是静态函数。

以下是 维基百科 的摘录:

单例模式的实现必须:

  • 确保单例类只存在一个实例;和
  • 提供对该实例的全局访问。

通常,这是通过以下方式完成的:

  • 将类的所有构造函数声明为私有;和
  • 提供一个返回实例引用的静态方法。

实例通常存储为私有静态变量;该实例是在变量初始化时创建的,在第一次调用静态方法之前的某个时间点。

原文由 cse 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题