【发布时间】:2021-03-10 02:37:52
【问题描述】:
情况
我使用的一些第三方 API 适用于原始指针,但我的客户端代码中都有智能指针。
问题
当我想围绕 API 编写一个包装函数时,我面临一个问题:是传递共享指针还是它们下面的原始指针作为参数。
像这样:
智能指针版本
// 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());
问题
- 就性能和内存安全而言,哪种方法更好?
- 引用计数在两种方法之间的工作方式会略有不同吗?
如果有一天该函数必须与其他类型的内存管理一起使用,我认为第二个版本更可重用。
【问题讨论】:
-
如果函数与对象的所有权有关,它应该接受一个共享指针。如果不是,则接受原始指针或引用。
-
@n.'pronouns'm。只有当智能指针不(ab)用作业务对象时,该建议才有效,而且在 OP 的代码中似乎就是这种情况——“我的客户端代码中都有智能指针”。在这种情况下,传递业务对象(即智能指针)似乎是更简洁的方法。更好的方法是让客户端代码处理正确封装的对象,而不是
std::shared_ptrs。 -
如果你会通过
const std::shared_ptr<>&,那么从性能上看没有区别。引用计数的工作原理完全相同,因为计数器不会增加。但是如果你将std::shared_ptr按值传递,那就有区别了。
标签: c++ performance pointers memory