何时通过引用传递以及何时通过C ++中的指针传递?

时间:2010-08-31 20:42:16

标签: c++

常见情况:

  1. 将std :: string传递给函数foo(std :: string *)或foo(std :: string&);
  2. 将tr1 :: shared_ptr传递给函数foo(tr1 :: shared_ptr * ptr)或foo(tr1 :: shared_ptr& ptr);
  3. 总的来说,什么是好的做法。我总是感到困惑。首先,将所有内容作为引用传递似乎是一致的,但是不可能将Literals作为引用或NULL作为引用传递。

    类似地,将所有内容作为指针似乎都很好,但是我必须担心指针可能指向NULL并在该函数的开头检查这些条件。

    您认为以下代码段是否合适?

    #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;
    }
    

    由于 阿贾伊

8 个答案:

答案 0 :(得分:25)

参考文献更容易正确。

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

特别是,当一个参数传递给一个函数,并且该函数不会改变它,并且它不是一个内置类型时,传递const引用。它与pass by value非常相似,除了它不需要复制构造函数调用。

指针非常有用,因为它们具有可以测试的无效值。有时这是无关紧要的,有时它非常重要。当然,你通常不能通过指针传递文字,除非(如果是字符串文字)它已经是。

某些编码标准表示非const引用不应该传递任何内容,因为它在调用时没有提供参数可能被函数更改的指示。在这种情况下,您将被要求通过指针。我不赞成这一点,特别是因为编程工具使得获取函数签名变得更容易和容易,因此您可以查看函数是否可以更改参数。但是,在组或企业中工作时,样式一致性比任何单个样式元素都重要。

答案 1 :(得分:23)

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

答案 2 :(得分:6)

在我之前的工作中,我们的规则是普通的参考文献实际上从未使用过。相反,我们同意:

  • 传递值(对于复制对象的便宜,所有基元,小值类型, std :: string ,非常小或重新计算的字符串)
  • 传递const引用(用于只读访问大对象)
  • 如果您需要读写访问权限,
  • 通过指针传递

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

答案 3 :(得分:5)

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

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");

为什么你在这里插手shared_ptr?这种情况肯定不需要它!

答案 4 :(得分:3)

可能不是问题的答案。只是吻。

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;
}

答案 5 :(得分:2)

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

我猜没有“正确”的答案。考虑到项目的具体情况,您需要权衡每种方法的优缺点。

我个人更喜欢参考文献,但无论如何我都建议您阅读这些帖子并思考它。

答案 6 :(得分:2)

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

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

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

您通常希望按原值传递的原始类型,因为这样的开销很小。那就是你大部分时间都在使用文字的时候。对于字符串,您应该尝试使用std::string并尽可能远离const char* C风格的字符串。当然,如果你必须使用C字符串,那么你别无选择,只能使用指针,但所有引用都应该是可行的方法。

哦,要真正做到异常安全,尽量避免这种情况:

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

取而代之的是:

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

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

答案 7 :(得分:1)

我更喜欢

    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;

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

我真的没有看到这是如何解决你的q,这是关于ref vs ptr的优点。在这两个例子中,你引用我希望使用第二种(ref)形式。