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

常见情况:

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

一般来说,什么是好的做法。 我总是感到困惑。 首先,传递所有参数似乎是一致的,但不可能将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; } 

谢谢Ajay

参考文献更容易得到正确的。

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

特别是,当一个parameter passing给一个函数,并且函数不会改变它,而且它不是一个内置types,通过const引用传递。 除了不需要复制构造函数调用之外,它的工作原理与传值相同。

指针是有用的,他们有一个保证无效的值,你可以testing。 有时候这是无关紧要的,有时这是非常重要的。 当然,除非(在string文字的情况下)已经存在,否则通常不能通过指针传递字面值。

一些编码标准认为,任何东西都不应该由非const引用传递,因为它在调用的地方没有提供参数可能被函数改变的指示。 在这种情况下,你将被要求通过指针。 我不赞成这一点,特别是编程工具使得函数签名变得更容易和容易,所以你可以看到一个函数是否可以改变一个参数。 然而,在一个团队或一个企业工作时,风格一致性比任何单个风格元素都重要。

一个好的经验法则是:“当可以的时候使用引用,当你需要的时候使用指针”。

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

 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 ? 情况当然不要求它!

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

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

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

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

我个人更喜欢参考,但我build议反正阅读这些post和思考。

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

NULL的目的是什么? 指示一个无效的指针/对象。 如果你打算把无效的对象传给一个函数,那么你所要做的就是检查一个对象的有效性。 如:

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

无论如何,你通常想要传值的原始types,因为有这么小的开销。 那就是当你大部分时间使用文字的时候。 对于string,你应该尝试使用std::string ,尽可能远离const char* C风格的string。 当然,如果你不得不使用Cstring,那么你别无select,只能使用指针,但是所有引用都应该是要走的路。

哦,要真正的例外安全,尽量避免这种情况:

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

相反:

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

看看RAII和exception安全为什么这是首选的方法。

在我以前的工作中,我们有这样一条规则:纯粹的引用实际上从来没有用过。 相反,我们同意:

  • 按值传递(便宜地复制对象,所有基本types,小值types, std :: string ,非常小的或refcounted的string)
  • 通过const引用传递(用于只读访问大对象)
  • 如果您需要读写权限,则通过指针传递

如果每个人都遵循这些规则,那么可以假定传递给函数的参数不会被修改,除非他们的地址被占用了。 它为我们工作。

我会比较喜欢

  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; 

因为这可以确保您的本地variables处理是exception安全的。

不过,我真的不知道这是怎么解决你的问题,这是关于裁判和ptr的优点。 在你引用的两个例子中,我都希望使用第二个(ref)表单。