如何使用 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 指针出现问题。
#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)
才能进行适当的清理,在这种情况下,您可以将库清理函数包装在自定义删除器中。
我有一个需要使用的 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 指针出现问题。
#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)
才能进行适当的清理,在这种情况下,您可以将库清理函数包装在自定义删除器中。