【问题标题】:Trying to return a `std::unique_ptr` constructed with `NULL`试图返回一个用 NULL 构造的 std::unique_ptr
【发布时间】:2015-08-25 12:53:44
【问题描述】:

我正在设计一个创建不同类型 Foo 的工厂,并且我正在尝试使用智能指针。

大多数似乎运行良好,但由于编译器限制,我缺少一些重要功能(即nullptr)。

我有这个方法:

std::unique_ptr<Foo> createFoo(const std::string &fooType) {
    auto it = _registeredFoo.find(fooType); // _registeredFoo is a map
    if(it != _registeredFoo.end())
       return std::unique_ptr<Foo>(it->second());
    return std::unique_ptr<Foo>(NULL);
}

当我测试这个方法时,它从不返回类似NULL 的指针。

这就是我测试我的方法的方式。

std::unique_ptr<Foo> _foo = FooFactory::getInstance()->createFoo("FOO"); //FOO is registered
if(_foo) {
  std::cout << "Hello, World!" << std::endl;
} else {
  std::cout << "Goodbye, World!" << std::endl;
}

std::unique_ptr<Foo> _bar = FooFactory::getInstance()->createFoo("BAR"); // BAR is unregisered
if(_bar) {
  std::cout << "Hello, World!" << std::endl;
} else {
  std::cout << "Goodbye, World!" << std::endl;
}

我总是看到“Hello, World!”

这让我相信我对std::unique_ptr 的构造函数的使用有点滥用。谁能给我一个建议,告诉我如何在没有emulating nullptr myself 的情况下解决这个问题?

我使用的是 gcc 4.4.6。

【问题讨论】:

  • 不会简单地使用unique_ptr();帮助吗?
  • 其实和default constructor是一样的。你如何检查你的代码“从不返回NULL-like指针”
  • “当我测试这个方法时,它从不返回类似 NULL 的指针。” 这是你问题中唯一真正的问题,但它缺乏细节.你能更好地解释你的问题吗?
  • GCC 4.4.6 已经过时了。当它说“C++0x 支持是实验性的”时,它是真的。如果可能,请升级。你生活在边缘。
  • 呃,您知道您的代码可能会导致双重释放和/或内存泄漏,尤其是当您让unique_ptr 正常工作时?您将指向内存的所有权从注册表传递给您返回的unique_ptrunique_ptr 将调用delete,您的注册表可能会调用delete。如果您使用相同的参数调用 createFoo 两次,也会出现同样的问题。

标签: c++ c++11


【解决方案1】:

我认为你想要的是一个空的unique_ptr

return std::unique_ptr<Foo>();

您似乎正在寻找一个不指向任何对象的指针(转换为 bool 时为 false)。

【讨论】:

  • 尝试delete“NULL 地址”处的对象没有任何问题。坦率地说,我不明白为什么 OP 的代码不应该工作。
  • 一个 NULL 的 shared_ptr 是有效的,但它几乎不是惯用的。
  • When Istd::unique_ptr&lt;Foo&gt;(NULL) 转换为 bool确实得到错误。
  • 我真的认为这虽然是一个有效的建议,但并不能解决 OP 的问题(无论是什么问题)。
【解决方案2】:

您可以使用默认的constructorstd::unique_ptr

std::unique_ptr<int> a1();
std::unique_ptr<int> a2(nullptr);

a1a2 是初始化为空的唯一指针(不拥有任何内容)。

您可以使用 unique_ptr 类提供的operator bool 来验证指针是否为空:

if (!a1) { // the smart pointer is empty
}

【讨论】:

    【解决方案3】:

    你想要的是

    return {};
    

    {} 返回任何(类)类型1 的默认构造对象,并且可以读取为“无”。它适用于智能指针、可选指针以及几乎所有内容。

    如果你的编译器缺少这个

    return std::unique_ptr<Foo>();
    

    会做的。将NULL 传递给std::unique_ptr 在C++11 中是不合法的,无论如何(the constructor is ambiguous)

    您没有 C++11 编译器。在您的代码中使用 C++11 将容易出错。


    1 正确的措辞是complicated。对于标量(如int),这会将值初始化为零(实际上,将值设置为0/null/0.0/'\0' 等)。

    【讨论】:

    • 你的第一个脚注是什么?
    • @Barry 试图解开 C++11 留给我们的初始化单词意大利面条。我现在做了一个简短的尝试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 2021-05-27
    • 1970-01-01
    相关资源
    最近更新 更多