如何使用 returns 原始指针函数中的智能指针

How to use smart pointer from function that returns a raw pointer

我有一个需要使用的 C++ 库,它使用 build() 函数通过原始指针 return 具有 new 的对象。我想在使用智能指针时使用此对象,但到目前为止我只找到了使用 smart_ptr.reset(build()) 的解决方案,该解决方案有效但有点难看。有没有更好的方法,还是我必须使用手动内存管理?

对于更多上下文,库中的函数调用 return new,我确定您需要在该指针上调用 delete。

这是我之前的答案,我称它为“丑陋”,也是我问是否有更好的方法的原因。

视情况而定。考虑这个例子:

struct example {
    ~example() { std::cout << "bye\n"; }
};

example* some_lib_function_A(){
    return new example;
}

库 return 为您提供了指向动态分配对象的原始指针。这不是很好,为了避免处理原始拥有指针,您可以将 some_lib_function_A 包装到一个函数中,该函数 return 是管理对象的智能指针。

然而,图书馆也可能会做一些类似的事情(只是为了争论。它应该 return 一个参考):

example* some_lib_function_B() {
    static example ex;
    return &ex;
} 

并且在这种情况下,您无法 delete 没有 运行 的 returned 指针出现问题。

Complete example:

#include <memory>
#include <iostream>
struct example {
    ~example() { std::cout << "bye\n"; }
};

example* some_lib_function_A(){
    return new example;
}

example* some_lib_function_B() {
    static example ex;
    return &ex;
} 

template <typename F>
std::unique_ptr<example> wrap(F f){
    std::unique_ptr<example> res;
    res.reset(f());
    return res;
}

int main() {
    wrap(some_lib_function_A);
    wrap(some_lib_function_B); // free(): invalid pointer
}

main 中的第一行符合您的预期,但第二行导致未定义的行为。这就是链接的答案说按照以下方式编写函数是不好的原因:

 std::unique_ptr<example> wrap_bad(example& ex) {
    std::unique_ptr<example> res;
    res.reset(&ex);
    return res;
 }

因为你无法知道传递给函数的 example 是否是动态分配的。该函数在其作用上撒谎,因为采用引用的函数与处理其参数的生命周期无关。可以正确使用,但错误使用的可能性很大。

您必须阅读库文档并找出库希望您使用指针做什么。有时您必须调用一些库函数 clean_up(ex) 才能进行适当的清理,在这种情况下,您可以将库清理函数包装在自定义删除器中。