我的函数是否接受指针或智能指针

Should my functions accept pointers or smart pointers?

本文关键字:指针 智能 函数 是否 我的      更新时间:2023-10-16

我已经开始使用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或根本不,但请指出我适当的地方,如果这不是。

你所说的答案是正确的。

如果你有一个函数应该在任何现有的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情况。

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

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

无论是引用TFile &还是指针TFile *都可以。

有些人会告诉你,当空指针是函数的无效输入时,你"应该"使用引用。这些人变得困惑和愤怒,当他们试图使用标准函数,如std::strlen, std::memcpy等,继承自C.我的感觉是,虽然它是很好的使用引用来自我文档的引用是必需的,它也很好,让你的API工作要么一致的引用或一致的指针。

有人会告诉你"不应该"使用非const引用形参,而应该使用指针。当他们尝试使用像std::swap这样的标准函数时,他们会感到困惑和愤怒,因为对C程序员来说,这看起来像按值传递,所以它"不应该"修改输入。

只要你不和他们中的任何一个人一起工作,你可以自己做选择。

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

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