情况
我使用的一些第三方API可以使用原始指针,但我的客户机代码中到处都是智能指针。
问题
当我想围绕API编写 Package 函数时,我面临一个问题:是否将共享指针或其下面的原始指针作为参数传递。
就像这样:
智能指针版本
// my wrapper
void MyWrapper(const std::shared_ptr<MyClassA>& pInObj, std::shared_ptr<MyClassB>& out_pOutObj) {
ThirdParty_DoStuff(pInObj.get(), out_pOutObj.get());
}
// my client code
auto inObj = std::make_shared<MyClassA>();
auto outObj = std::make_shared<MyClassB>();
MyWrapper(inObj, outObj);
原始指针版本
// wrapper
void MyWrapper(MyClassA* pInObj, MyClassB* out_pOutObj) {
assert(pInObj && out_pOutObj);
ThirdParty_DoStuff(pInObj, out_pOutObj);
}
// client code
auto inObj = std::make_shared<MyClassA>();
auto outObj = std::make_shared<MyClassB>();
MyWrapper(inObj.get(), outObj.get());
提问
- 就性能和内存安全性而言,哪种方法更好?
- 这两种方法的引用计数工作方式是否略有不同?
我认为第二个版本更可重用,如果有一天该函数必须与其他类型的内存管理一起工作。
2条答案
按热度按时间vmdwslir1#
我建议使用以下方法来查看代码:
weak_ptr
,但对于这个,它可能不值得一看。所以对于你的例子,我们可以看到
ThirdParty_DoStuff
没有所有权,所以我们也不会,所以你可以选择引用和指针,这取决于参数是否是强制性的。**编辑:**从c++17开始,你可以选择使用
optional
这也可以涵盖你有一个可选输出的情况。ntjbwcob2#
我建议使用引用/原始指针,这取决于你是否想传递
nullptr
。为什么呢?这是一个很好的指导方针,尽可能少地传递-如果你不需要增加引用计数或做任何特定的shared_ptr
传递,它不是必需的,可能会产生误导。关于你的问题-如果 Package 的API可以处理
nullptr
,这两个都是相当安全的。如果没有(这是你的assert
建议的),引用会更安全。引用计数对于所有方法都是一样的,因为你是通过引用传递的。如果你通过值传递,它会增加函数调用的引用计数。
总而言之,我建议的解决方案: