简体   繁体   English

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

[英]Should my functions accept pointers or smart pointers?

I've started making use of std::unique_ptr eg: 我开始使用std::unique_ptr例如:

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

instead of 代替

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

Now I'm not sure what my functions should look like. 现在我不确定我的功能应该是什么样子。 I think part of the problem might be that my code is not complicated enough yet for any problems to become apparent but I'd like to get it right now so I don't end up in a mess when things are more complicated. 我认为问题的一部分可能是我的代码还不够复杂,任何问题都不会显而易见但是我现在想要解决它,所以当事情变得更复杂时我不会陷入混乱。

I used to have: 我曾经有过:

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

(which doesn't actually modify TFile but can't be const because it calls some non-const functions of TFile). (它实际上并没有修改TFile但不能是const因为它调用TFile的一些非const函数)。

I could still call this by doing: 我仍然可以这样做:

myResult  = interestingResult( myfile.get() );

which doesn't seem very user friendly. 这似乎不是非常用户友好。 (I think it is suggested here: https://stackoverflow.com/a/5325560/1527126 .) (我认为这里建议: https//stackoverflow.com/a/5325560/1527126 。)

Or I could modify my function to look like: 或者我可以修改我的功能看起来像:

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

which forces the user to always use a unique_ptr. 这会强制用户始终使用unique_ptr。

or I could support both by writing: 或者我可以通过写作来支持两者:

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

but I don't see that in other people's code. 但我没有在其他人的代码中看到这一点。

What is the standard approach to this situation? 这种情况的标准方法是什么?

I think this answer ( https://stackoverflow.com/a/9700189/1527126 ) implies I should accept references since I don't expect myfile to be null. 我认为这个答案( https://stackoverflow.com/a/9700189/1527126 )暗示我应该接受引用,因为我不希望myfile为null。 But the library function TFile::Open always returns a pointer so it seems natural to be able to pass that straight into the function without extra dereferencing. 但是库函数TFile::Open总是返回一个指针,因此在没有额外解除引用的情况下将其直接传递给函数似乎很自然。

Apologetic ps I gave up trying to work out whether I should ask on StackOverflow or CodeReview or not at all but please point me to the appropriate place if this is not it. apologetic ps我放弃了试图弄清楚我是否应该在StackOverflow或CodeReview上询问,但是如果不是这样,请指出我到合适的地方。

The answer you are referring to is the right one. 你指的答案是对的。

If you have a function that should work on any existing TFile instance and has no reason to accept NULL pointers as a valid argument and where the function argument does not carry ownership, you should use TFile& as parameter type ( TFile const& where possible). 如果你有一个应该在任何现有TFile实例上工作的函数,并且没有理由接受NULL指针作为有效参数,并且函数参数不带有所有权,那么你应该使用TFile&作为参数类型( TFile const&尽可能)。 That the object being passed in is held by pointer (with or without ownership) by the caller should not make a difference to that function. 传入的对象由调用者(有或没有所有权)保持,不应该对该函数产生影响。

You could choose to use a TFile * argument, but that creates at least ambiguity over validity of passing NULL, so may cause problems in the future. 您可以选择使用TFile *参数,但这至少会产生对传递NULL的有效性的歧义,因此将来可能会导致问题。

If you use a unique_ptr<TFile> argument, you pass ownership of the object into the function for good. 如果使用unique_ptr<TFile>参数,则将对象的所有权传递给函数。 The caller will be left with a NULL unique_ptr when the call returns. 当调用返回时,调用者将留下NULL unique_ptr

If you use a unique_ptr<TFile>& argument, this indicates that the function can choose to take over ownership of the object or leave it to the caller. 如果使用unique_ptr<TFile>&参数,则表示该函数可以选择接管对象的所有权或将其留给调用者。 Rather unusual. 相当不寻常。

A unique_ptr<TFile> const& argument could be used like a TFile * , but forces the caller to own the object and to manage it using a unique_ptr . unique_ptr<TFile> const& argument可以像TFile *一样使用,但强制调用者拥有该对象并使用unique_ptr对其进行管理。 Why should such a requirement be imposed on the caller? 为什么要对呼叫者施加这样的要求? Of course this (and the other uses of unique_ptr ) all also have to deal with the NULL case. 当然这(以及unique_ptr的其他用途)都必须处理NULL情况。

The problem with accepting smart pointers in the parameter list is you dictate what kind of smart pointer the caller can use. 接受参数列表中的智能指针的问题是你指定调用者可以使用哪种智能指针。 For example, by using unique_ptr you prevent the caller from using a shared_ptr instead. 例如,通过使用unique_ptr可以防止调用者使用shared_ptr。

In your case, I'd suggest a reference parameter. 在你的情况下,我建议一个参考参数。 I also see regular pointers used a lot as well. 我也看到常用指针也很常用。 The main thing is that your function doesn't try to hold a reference / take ownership of the object after the function returns - ie it's not later responsible for freeing the memory. 主要的是你的函数在函数返回后不会尝试持有引用/获取对象的所有权 - 即它不会在以后负责释放内存。

Either a reference TFile & or a pointer TFile * is fine. 引用TFile &或指针TFile *都可以。

There are people who will tell you that you "should" use a reference when a null pointer is an invalid input to the function. 当空指针是函数的无效输入时,有人会告诉您“应该”使用引用。 These people become confused and angry when they try to use standard functions like std::strlen , std::memcpy etc, inherited from C. My feeling is that while it's quite nice to use references to self-document that a referand is required, it's also quite nice to have your API work either consistently with references or consistently with pointers. 当他们尝试使用从C继承的标准函数(如std::strlenstd::memcpy等)时,这些人会感到困惑和愤怒。我的感觉是,虽然使用自我文档的引用是非常好的,但是需要一个referand,让API与引用保持一致或与指针一致地工作也很好。

There are people who will tell you that you "should not" use a non-const reference parameter, preferring a pointer. 有人会告诉你,你“不应该”使用非const引用参数,而是更喜欢指针。 They become confused and angry when they try to use standard functions like std::swap , because to a C programmer that looks like pass-by-value and so it "should not" modify the input. 当他们尝试使用标准函数(如std::swap时,他们会感到困惑和愤怒,因为对于一个看起来像值传递的C程序员而言,它“不应该”修改输入。

As long as you don't work with either of those people, you can make your own choice. 只要您不与这两个人合作,您就可以自己做出选择。

It depends, but using raw pointers(or references to object) in functions prefered, because functions do not take ownership of pointer. 这取决于,但在首选函数中使用原始指针(或对象的引用),因为函数不占用指针的所有权。

And also if one day you'll decide to use shared_ptr 's... 而且如果有一天你决定使用shared_ptr的......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM