2013-03-13 54 views
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的一些非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,或者根本没有,但请指出我适当的地方,如果不是这样。

+0

使用参考? – Nim 2013-03-13 16:36:29

回答

2

参考TFile &或指针TFile *是好的。

有些人会告诉你,当空指针是函数的无效输入时,你应该“使用”一个引用。当他们尝试使用从C继承的std::strlenstd::memcpy等标准函数时,这些人会感到困惑和愤怒。我的感觉是,尽管使用引用自身文档的引用是需要referand的,但它也是很好的你的API工作要么与引用一致,要么与指针一致。

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

只要你不与这些人一起工作,你可以自己选择。

+0

当NULL值无效时使用指针类型定时会导致维护问题。充其量,它充分利用了NULL的运行时问题 - 需要重复检查和通道来指示错误情况。否则它会导致崩溃或更糟,如果有一个NULL可以滑过的调用路径。如果它的项目风格或者你害怕非const引用,那就是你必须做的 - 但是你应该知道后果。仅供参考:我不害怕在C(-style)代码中使用'strcpy',但是当我获得选择时,我会使用字符串类而不是裸C字符串。 – JoergB 2013-03-13 17:02:03

+1

@JoergB:我没有看到那些经常维护的问题,在采用指针的代码中更糟糕。那种在文档中不检查'null'是否是有效输入(即几乎任何人,在足够糟糕的一天)都不会在引用指针之前检查空值的麻烦的人。所以他们只是将'* p'传递给需要引用的函数,有时'p'在代码中为空,并且有人必须查找并修复它。 – 2013-03-13 17:03:28

+1

和FWIW,当我尝试使用带指针的函数时,我变得困惑和愤怒,但不明确地说空输入是否有效,因为对于作者来说,按照约定显而易见的是,如果函数接受一个指针,则空有效;-) – 2013-03-13 17:09:15

3

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

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

1

它取决于,但在函数中使用原始指针(或对象的引用),因为函数不会接受指针的所有权。

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

4

你指的是正确的答案。

如果有,应该在任何现有TFile比如工作,没有理由接受NULL指针作为一个有效参数,其中函数的论据没有所有权,你应该使用TFile&作为参数类型(TFile const&在可能的功能)。传入的对象由指针保存(不论是否拥有所有权)指针应该不会影响该函数。

您可以选择使用TFile *参数,但这会在传递NULL的有效性方面造成至少不明确性,因此可能会在将来导致问题。

如果您使用unique_ptr<TFile>参数,则将对象的所有权转移给该函数以保持良好状态。呼叫返回时,呼叫方将留下NULL unique_ptr

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

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