什么时候通过引用传递,什么时候在 C++ 中通过指针传递?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3613065/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:16:33  来源:igfitidea点击:

When to pass by reference and when to pass by pointer in C++?

c++

提问by user855

Common Situations:

常见情况:

  1. Passing std::string to a function foo(std::string*) or foo(std::string&);
  2. Passing tr1::shared_ptr to a function foo(tr1::shared_ptr* ptr) or foo(tr1::shared_ptr& ptr);
  1. 将 std::string 传递给函数 foo(std::string*) 或 foo(std::string&);
  2. 将 tr1::shared_ptr 传递给函数 foo(tr1::shared_ptr* ptr) 或 foo(tr1::shared_ptr& ptr);

In general, what is a good practice. I always get confused. At first, passing everything as references seems consistent, however it is not possible to pass in Literals as references or NULLs as references.

一般来说,什么是好的做法。我总是很困惑。起初,将所有内容作为引用传递似乎是一致的,但是不可能将 Literals 作为引用传递或 NULL 作为引用传递。

Similarly, having everything as pointers seems good, but having then I have to worry that pointers might be pointing to NULL and check for those conditions in the beginning of that function.

类似地,将所有内容都作为指针看起来不错,但是我不得不担心指针可能指向 NULL 并在该函数的开头检查这些条件。

Do you think the following snippet is good?

你认为下面的片段好吗?

#include <iostream>
#include <vector>
#include <map>
#include <string>
#include <tr1/memory>
#include <algorithm>
using namespace std;
using namespace std::tr1;

int main(){
        map<string, shared_ptr<vector<string> > > adjacencyMap;
        vector<string>* myFriends = new vector<string>();
        myFriends->push_back(string("a"));
        myFriends->push_back(string("v"));
        myFriends->push_back(string("g"));
        adjacencyMap["s"] = shared_ptr<vector<string> >(myFriends);
        return 0;
}

Thanks Ajay

谢谢阿杰

采纳答案by David Thornley

References are easier to get right.

参考文献更容易正确。

Is your problem with literals that you aren't using const references? You can't bind a temporary (produced by a literal) to a non-const reference, because it makes no sense to change one. You can bind one to a const reference.

您没有使用常量引用的文字有问题吗?您不能将临时(由文字产生)绑定到非常量引用,因为更改一个没有意义。您可以将一个绑定到一个常量引用。

In particular, when passing an argument to a function, and the function isn't going to change it, and it isn't a built-in type, pass by const reference. It works much the same as pass by value, except it doesn't require a copy constructor call.

特别是,当将参数传递给函数时,该函数不会更改它,并且它不是内置类型,请通过 const 引用传递。它的工作原理与按值传递非常相似,只是它不需要复制构造函数调用。

Pointers are useful in that they have a guaranteed invalid value you can test for. Sometimes this is irrelevant, and sometimes it's very important. Of course, you can't generally pass a literal by pointer, unless (in case of a string literal) it already is.

指针很有用,因为它们有一个可以测试的有保证的无效值。有时这无关紧要,有时却非常重要。当然,您通常不能通过指针传递文字,除非(在字符串文字的情况下)它已经是。

Some coding standards say that nothing should ever be passed by non-const reference, since it provides no indication at the point of call that the argument might be changed by the function. In that case, you will be required to pass by pointer. I don't favor this, particularly as programming tools make it easier and easier to get the function signature, so you can see if a function might change an argument. However, when working in a group or for an enterprise, style consistency is more important than any individual style element.

一些编码标准说非常量引用不应该传递任何东西,因为它在调用点不提供参数可能被函数更改的指示。在这种情况下,您将需要通过指针传递。我不赞成这样做,特别是因为编程工具使获取函数签名变得越来越容易,因此您可以查看函数是否可能更改参数。但是,在团队或企业中工作时,风格一致性比任何个人风格元素都更重要。

回答by Lucas

A good rule of thumb: "Use references when you can and pointers when you have to".

一个好的经验法则:“尽可能使用引用,必要时使用指针”。

回答by Lucas

In my previous job, we had the the rule that plain references were practically never used. Instead we agreed to:

在我之前的工作中,我们有一个规则,即几乎从不使用普通引用。相反,我们同意:

  • pass by value (for cheap to copy objects, all primitives, small value types, std::string, very small or refcounted strings)
  • pass by constreference (for readonly access to large objects)
  • pass by pointer if you need read-write access
  • 按值传递(为了廉价复制对象、所有原语、小值类型、std::string、非常小的或引用计数的字符串)
  • 通过const引用传递(用于对大对象的只读访问)
  • 如果您需要读写访问,则通过指针传递

If everybody follows these rules, you can assume that parameters passed to functions are not modified unless their adress was taken. It worked for us.

如果每个人都遵循这些规则,您可以假设传递给函数的参数不会被修改,除非它们的地址被占用。它对我们有用。

回答by Matthieu M.

I really don't understand why you got to all this trouble:

我真的不明白你为什么遇到这些麻烦:

std::map < std::string, std::vector<std::string> > adjacencyMap;
std::vector<std::string>& sFriends = adjacencyMap["s"];
sFriends.push_back("a");
sFriends.push_back("v");
sFriends.push_back("g");

Why do you meddle with shared_ptrhere ? The situation certainly does not call for it!

你为什么要插手shared_ptr这里?这种情况当然不需要它!

回答by ronag

Probably not an answer to the question. Just KISS.

可能不是问题的答案。吻就对了。

int main()
{
        multimap<string, string> adjacencyMap;
        adjacencyMap.insert(std::make_pair("s", "a"));
        adjacencyMap.insert(std::make_pair("s", "v"));
        adjacencyMap.insert(std::make_pair("s", "g"));
        return 0;
}

回答by Zoli

As a general rule of thumb, always try to pass parameters by reference to const. Passing pointers can lead to ownership issues as well as a bunch of other possibilities for subtle mistakes.

作为一般经验法则,始终尝试通过引用 const 来传递参数。传递指针可能会导致所有权问题以及一系列其他细微错误的可能性。

What is the purpose of NULL? To indicate an invalid pointer/object. If you're going to pass invalid objects to a function, then all you have to do is have a method for checking an object's validity. As in:

NULL 的目的是什么?指示无效的指针/对象。如果您要将无效对象传递给函数,那么您所要做的就是拥有一个检查对象有效性的方法。如:

void myfunc(const obj& myobj)
{
  if(myobj.valid())
    // DO SOMETHING
}

Primitive types you'd usually want to pass-by-value anyway, since there's such little overhead. And that's when you'd use literals most of the time anyway. For strings, you should try to use std::stringand stay away from const char*C-style strings as much as you can. Of course if you have to use C-strings, then you have no choice but to use pointers, but all in all references should be the way to go.

无论如何,您通常希望通过值传递原始类型,因为开销很小。无论如何,这就是您大部分时间都会使用文字的时候。对于字符串,您应该尽量使用std::string并远离const char*C 风格的字符串。当然,如果您必须使用 C 字符串,那么您别无选择,只能使用指针,但总而言之,引用应该是要走的路。

Oh and to be truly exception-safe try to avoid this:

哦,为了真正的异常安全,尽量避免这种情况:

vector<string>* myFriends = new vector<string>();
...
adjacencyMap["s"] = shared_ptr<vector<string> >(myFriends);

Instead do:

而是这样做:

shared_ptr<vector<string> > myFriends(new vector<string>());

Look in to RAII and exception safety for why this is the preferred method.

查看 RAII 和异常安全性,了解为什么这是首选方法。

回答by Sebastian

You can browse http://www.cplusplus.com/forum/beginner/3958/for some insights. Also useful: http://www.velocityreviews.com/forums/t284603-pointers-vs-references-a-question-on-style.html

您可以浏览http://www.cplusplus.com/forum/beginner/3958/以获得一些见解。也有用:http: //www.velocityreviews.com/forums/t284603-pointers-vs-references-a-question-on-style.html

I guess there is no "right" answer. You need to weight pros and cons of each approach taking into account the specific context of your project.

我想没有“正确”的答案。您需要考虑到项目的特定背景,权衡每种方法的利弊。

I personally prefer references, but I recommend anyways to read those posts and muse about it.

我个人更喜欢参考文献,但无论如何我建议阅读这些帖子并对其进行思考。

回答by Steve Townsend

I would prefer

我会选择

    map<string, shared_ptr<vector<string> > > adjacencyMap;
    shared_ptr<vector<string> > myFriends(new vector<string>());
    myFriends->push_back(string("a"));
    myFriends->push_back(string("v"));
    myFriends->push_back(string("g"));
    adjacencyMap["s"] = myFriends;
    return 0;

as this ensures your local var handling is exception-safe.

因为这可以确保您的本地 var 处理是异常安全的。

I don't really see how this addresses your q which was about the merits of ref vs ptr, though. In both of the examples you cite I would expect to use the second (ref) form.

不过,我真的不明白这如何解决您的 q,这与 ref 与 ptr 的优点有关。在您引用的两个示例中,我希望使用第二种(参考)形式。