c++ - 通过传递指针的地址来初始化 std::unique_ptr

标签 c++ c++11 unique-ptr

我正在创建一个与某些 Windows API 代码互操作的类,现在我必须初始化的指针之一是通过调用初始化它的 native 函数来完成的。

我的指针是 std::unique_ptr 类型,带有一个自定义删除器,它调用提供的 WinAPI 删除器函数,但是我不能将带有 & 地址运算符的 unique_ptr 传递给 init 函数.为什么?

我创建了一个示例来演示我的问题:

#include <memory>

struct foo
{
   int x;
};

struct custom_deleter {};

void init_foo(foo** init)
{
  *init = new foo();
}

int main()
{
   std::unique_ptr<foo, custom_deleter> foo_ptr;

   init_foo(&foo_ptr);
}

编译器咆哮着说:

source.cpp: In function 'int main()':
source.cpp:19:21: error: cannot convert 'std::unique_ptr<foo, custom_deleter>*' to 'foo**' for argument '1' to 'void init_foo(foo**)'

最佳答案

在某处,unique_ptr<foo>有一个类型为 foo* 的数据成员.

但是,类的用户直接修改该数据成员是不合法的。这样做不一定会保留 unique_ptr 的类不变量。 ,特别是它不会释放旧的指针值(如果有的话)。在您的特殊情况下,您不需要发生这种情况,因为之前的值为 0,但通常它应该发生。

因此unique_ptr不提供对数据成员的访问,仅提供对其值的拷贝(通过 get()operator-> )。您无法获得 foo**出你的unique_ptr .

你可以改为:

foo *tmp;
init_foo(&tmp);
std::unique_ptr<foo, custom_deleter> foo_ptr(tmp);

这是异常安全的,原因与 std::unique_ptr<foo, custom_deleter> foo_ptr(new foo()); 相同。是异常安全的:unique_ptr保证你传递给它的构造函数的任何东西最终都会被删除器删除。

顺便说一句,不是custom_deleter需要一个operator()(foo*) ?还是我错过了什么?

关于c++ - 通过传递指针的地址来初始化 std::unique_ptr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12403750/

相关文章:

C++智能指针混淆

c++ - 如何将 NULL 或 nullptr 传递给接收 unique_ptr 参数的函数?

c++ - 如何编码传出引用以使用 unique_ptr 在容器上搜索

c++ - Qt - "No such slot",虽然有

c++ - 类 Python C++ 装饰器

c++ - 继承的构造函数,在 clang++3.9 中编译,在 g++7 中失败

c++ - 在 Shift/Reduce 解析器生成器中指定 C++11 语法操作函数?

c++ - unique_ptr 到派生类作为函数的参数,该函数将 unique_ptr 带到基类

php - 哪种沟通方式更有效

c++ - 从 QT 可执行文件创建和删除 github 问题