我正在创建一个与某些 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/