c++ 是否将共享指针或原始指针传递给函数

mwyxok5s  于 2023-10-21  发布在  其他
关注(0)|答案(2)|浏览(94)

情况

我使用的一些第三方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());

提问

  • 就性能和内存安全性而言,哪种方法更好?
  • 这两种方法的引用计数工作方式是否略有不同?

我认为第二个版本更可重用,如果有一天该函数必须与其他类型的内存管理一起工作。

vmdwslir

vmdwslir1#

我建议使用以下方法来查看代码:

  • 还有一些其他选项,如weak_ptr,但对于这个,它可能不值得一看。

所以对于你的例子,我们可以看到ThirdParty_DoStuff没有所有权,所以我们也不会,所以你可以选择引用和指针,这取决于参数是否是强制性的。

**编辑:**从c++17开始,你可以选择使用optional这也可以涵盖你有一个可选输出的情况。

ntjbwcob

ntjbwcob2#

我建议使用引用/原始指针,这取决于你是否想传递nullptr。为什么呢?这是一个很好的指导方针,尽可能少地传递-如果你不需要增加引用计数或做任何特定的shared_ptr传递,它不是必需的,可能会产生误导。
关于你的问题-如果 Package 的API可以处理nullptr,这两个都是相当安全的。如果没有(这是你的assert建议的),引用会更安全。
引用计数对于所有方法都是一样的,因为你是通过引用传递的。如果你通过值传递,它会增加函数调用的引用计数。
总而言之,我建议的解决方案:

// wrapper

void MyWrapper(MyClassA& pInObj, MyClassB& out_pOutObj) {

    ThirdParty_DoStuff(&pInObj, &out_pOutObj);
}

// client code

auto inObj = std::make_shared<MyClassA>();
auto outObj = std::make_shared<MyClassB>();

MyWrapper(*inObj, *outObj);

相关问题