3

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

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

代替

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

现在我不确定我的功能应该是什么样子。我认为问题的一部分可能是我的代码还不够复杂,还不足以让任何问题变得明显,但我想现在就得到它,这样当事情变得更复杂时,我就不会陷入混乱。

我曾经有:

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

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

我仍然可以这样做:

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总是返回一个指针,因此能够将它直接传递给函数而不需要额外的解引用似乎很自然。

抱歉 ps 我放弃了尝试确定是否应该在 StackOverflow 或 CodeReview 上询问,但如果不是,请指出适当的位置。

4

4 回答 4

4

您所指的答案是正确的。

如果您有一个应该在任何现有TFile实例上工作的函数并且没有理由接受 NULL 指针作为有效参数并且函数参数不携带所有权,则应该使用TFile&作为参数类型(TFile const&如果可能)。传入的对象由调用者通过指针(有或没有所有权)持有,这不会对该函数产生影响。

您可以选择使用TFile *参数,但这至少会在传递 NULL 的有效性方面产生歧义,因此可能会在未来引起问题。

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

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

unique_ptr<TFile> const&参数可以像 a 一样使用,TFile *但会强制调用者拥有对象并使用 a 来管理它unique_ptr。为什么要对调用者提出这样的要求?当然,这(以及 的其他用途unique_ptr)也都必须处理 NULL 情况。

于 2013-03-13T16:43:01.517 回答
3

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

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

于 2013-03-13T16:39:35.337 回答
2

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

有些人会告诉你,当空指针是函数的无效输入时,你“应该”使用引用。这些人在尝试使用继承自 C 的标准函数(如 等)时变得困惑和愤怒std::strlenstd::memcpy我的感觉是,虽然使用对需要引用的自文档的引用非常好,但拥有您的 API 也非常好要么与引用一致,要么与指针一致。

有些人会告诉你“不应该”使用非常量引用参数,而更喜欢指针。当他们尝试使用标准函数std::swap(如

只要您不与这些人中的任何一个合作,您就可以做出自己的选择。

于 2013-03-13T16:53:38.400 回答
1

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

而且,如果有一天你决定使用shared_ptr's...

于 2013-03-13T16:41:03.750 回答