Mik*_*lya 5 c++ api smart-pointers c++11
除了一些罕见的情况之外,通常建议不要在现代C++中使用原始指针.在C++库API中使用智能指针的常见做法是什么?
以下用例出现在我的脑海中:
Mat*_* M. 13
不幸的是,库API设计远远超出了语言本身的规则:突然你必须关心实现细节,比如ABI.
与C相反,常见的实现可以轻松地一起交互,C++实现具有非常不同的ABI(用于VC++的Microsoft ABI与gcc和Clang使用的Itanium ABI完全不兼容),并且C++标准库实现也彼此不兼容,因此如果std::类出现在接口中,那么使用libstdc ++(与gcc捆绑)编译的库不能被使用另一个主要版本的libstdc ++的程序或其他实现(如libc ++(与Clang捆绑))使用.
因此,它实际上取决于您是否希望将库作为二进制文件提供,或者假设用户可以使用自己的编译器和选择的标准库实现来编译库.只有在后一种情况下,你应该暴露一个C++接口,对于坚持C的二进制发行版更好(并且它也更容易与其他语言集成).
有了这个,我们假设您决定使用C++ API:
1)返回新对象的函数.
如果可以按值返回对象,请执行此操作; 如果它是多态的,请使用std::unique_ptr<Object>.
2)返回新对象的函数,但它也创建了对该对象的另一个引用.
罕见案例.我想你的意思是它以某种方式保留了参考.在这种情况下,您拥有共享所有权,因此显而易见的选择std::shared_ptr<Object>.
3)仅使用它接收的对象作为参数的函数.
比最初看起来要复杂得多,甚至假设没有保留对象的引用.
const或不通过)4)接管对象所有权的函数.
简单的所有权:std::unique_ptr<Object>.
5)一个函数,它将存储对作为参数接收的对象的引用,但可能存在对同一对象的其他引用(来自调用方).
共享所有权: std::shared_ptr<Object>
在一般情况下,唯一指针可以完成工作.
std::unique_ptr<Foo> func();
Run Code Online (Sandbox Code Playgroud)
这样您就可以将它们直接分配给auto调用者站点的变量,而不用担心内存管理.
auto u = func();
Run Code Online (Sandbox Code Playgroud)
如果您需要共享所有权,您可以在调用者站点上转换智能指针:
std::shared_ptr<Foo> s{func()};
Run Code Online (Sandbox Code Playgroud)
但是,如果函数的返回类型不是多态的,并且该类型移动速度很快,您可能更喜欢按值返回:
Foo func();
Run Code Online (Sandbox Code Playgroud)共享指针.
std::shared_ptr<Foo> func();
Run Code Online (Sandbox Code Playgroud)只需使用对象的引用或const引用,在调用者站点上使用原始指针或智能指针"取消引用".
void func(Foo& obj);
void func(const Foo& obj);
Run Code Online (Sandbox Code Playgroud)
如果参数是可选的,您可以使用原始指针,以便您可以轻松地将nullptr它们传递给它们.
void func(Foo *obj);
void func(const Foo *obj);
Run Code Online (Sandbox Code Playgroud)独特的指针.
void func(std::unique_ptr<Foo> obj);
Run Code Online (Sandbox Code Playgroud)Const对共享指针的引用.
void func(const std::shared_ptr<Foo>& obj);
Run Code Online (Sandbox Code Playgroud)
const引用(对共享指针)只是一个优化,以防止在调用函数和返回时调整引用计数.