我的函数应该接受指针还是智能指针?

时间:2013-03-13 16:33:41

标签: c++ function unique-ptr

我开始使用std::unique_ptr例如:

unique_ptr<TFile> myfile( TFile::Open("myfile.root") );

而不是

TFile * myoldfile = TFile::Open("myoldfile.root") ;

现在我不确定我的功能应该是什么样的。我认为问题的一部分可能是我的代码不够复杂,但任何问题都没有明显,但我现在想要把它弄好,所以当事情变得更复杂时,我不会陷入混乱。

我曾经有过:

double interestingResult( TFile * input )
{...}

(实际上并没有修改TFile但不能是const,因为它调用了TFile的一些非const函数)。

我仍然可以这样做:

myResult  = interestingResult( myfile.get() );

这似乎不是非常用户友好。 (我认为这里建议:https://stackoverflow.com/a/5325560/1527126。)

或者我可以将我的功能修改为:

double interestingResult( unique_ptr<TFile>& input )
{...}

强制用户始终使用unique_ptr。

或者我可以通过写作来支持两者:

double interestingResult( unique_ptr<TFile>& input )
{ return interestingResult( intput.get() ); }

但我没有在其他人的代码中看到这一点。

这种情况的标准方法是什么?

我认为这个答案(https://stackoverflow.com/a/9700189/1527126)意味着我应该接受引用,因为我不希望myfile为空。但是库函数TFile::Open总是返回一个指针,所以在没有额外解除引用的情况下将它直接传递给函数似乎很自然。

抱歉的p.s.我放弃了试图弄清楚我是否应该在StackOverflow或CodeReview上询问,但是如果不是这样的话,请指出我所在的位置。

4 个答案:

答案 0 :(得分:4)

你所指的答案是对的。

如果你的函数应该适用于任何现有的TFile实例,并且没有理由接受NULL指针作为有效参数,并且函数参数不具有所有权,那么你应该使用TFile&作为参数类型(尽可能TFile const&)。传入的对象由调用者(有或没有所有权)保持,不应该对该函数产生影响。

您可以选择使用TFile *参数,但这至少会产生传递NULL的有效性歧义,因此将来可能会出现问题。

如果使用unique_ptr<TFile>参数,则将对象的所有权传递给函数。当呼叫返回时,呼叫者将留下NULL unique_ptr

如果使用unique_ptr<TFile>&参数,则表示该函数可以选择接管对象的所有权或将其留给调用者。相当不寻常。

unique_ptr<TFile> const&参数可以像TFile *一样使用,但强制调用者拥有该对象并使用unique_ptr进行管理。为什么要对呼叫者施加这样的要求?当然,这(以及unique_ptr的其他用途)都必须处理NULL情况。

答案 1 :(得分:3)

接受参数列表中的智能指针的问题是你指定调用者可以使用哪种智能指针。例如,通过使用unique_ptr,可以防止调用者使用shared_ptr。

在你的情况下,我建议一个参考参数。我也看到常用指针也很常用。主要的是你的函数在函数返回后不会试图保持对象的引用/取得所有权 - 即它不会在以后负责释放内存。

答案 2 :(得分:2)

引用TFile &或指针TFile *都可以。

当空指针是函数的无效输入时,有人会告诉您“应该”使用引用。当他们尝试使用从C继承的std::strlenstd::memcpy等标准函数时,这些人会感到困惑和愤怒。我的感觉是,虽然使用引用自我文档很好,但是参考资料是要求,让你的API与引用一致或与指针一致地工作也很好。

有些人会告诉你,你“不应该”使用非const引用参数,而更喜欢使用指针。当他们尝试使用像std::swap这样的标准函数时,他们会感到困惑和愤怒,因为对于一个看起来像值传递的C程序员而言,它“不应该”修改输入。

只要您不与这两个人合作,您就可以自己做出选择。

答案 3 :(得分:1)

这取决于,但在首选函数中使用原始指针(或对象的引用),因为函数不占用指针。

如果有一天你决定使用shared_ptr的话......