如何通过引用从原始指针创建 unique_ptr?

QF0*_*QF0 -1 c++ smart-pointers

我正在调用一个库函数,它返回一个指向类对象的原始指针,但我想将返回的指针包装在unique_ptr. 我不知道库如何创建指针,但我假设它使用new(请参阅下面代码中的注释)。

下面的代码是创建unique_ptr并通过函数调用引用返回它的有效方法吗?该代码确实打印“42”,但是有更好的方法吗?


该库是 MariaDB C++ 连接器。不幸的是,它的文档很少。几天前我在SO上询问过这个问题,但到目前为止还没有得到答复。我本来会使用 MySQL 版本,但似乎并没有好多少。但是,有一个示例程序,其中包含以下行main

std::unique_ptr<sql::Connection> conn(driver->connect(url, properties));
Run Code Online (Sandbox Code Playgroud)

因此,在阅读了评论和答案后,我想我现在可以假设Connection我想要的对象已被new编辑。另一方面,为什么我通过引用传递而不是仅仅返回unique_ptr- 好问题。唯一的原因是该应用程序中的所有其他代码都返回 abool作为成功状态,因此我认为在这里执行相同的操作会更加一致。

原始代码:

#include <memory>
#include <iostream>

class A {
public:
   int b;
   A() : b(42) {}
};

void create(std::unique_ptr<A> &p) {
   A *a = new A; // this is actually a function call which returns an A*
   p.reset(a);
}

int main() {
   std::unique_ptr<A> foo;
   create(foo);
   std::cout << "foo.b is " << foo->b << '\n';
}
Run Code Online (Sandbox Code Playgroud)

gua*_*rd3 6

当且仅当指针是用 . 创建时,您编写的内容才有效new。但即便如此,仅仅delete'ing 它可能还不足以正确地取消初始化它,因此您应该始终坚持根据库的文档来管理此指针。

但是,智能指针旨在通过允许您使用自定义删除器功能来解决此类情况。

所以,正确的方法是这样的:

using my_ptr_t = std::unique_ptr<A, void(*)(A*)>;

void create(my_ptr_t& out) {
    A* a = ... // get the pointer
    out = my_ptr_t(a, [](A* p) -> void {
        // Uninitialize the pointer as dictated
        // by the library's documentation
        ...
    });
};
Run Code Online (Sandbox Code Playgroud)