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)
当且仅当指针是用 . 创建时,您编写的内容才有效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)