常见情况:
总的来说,什么是好的做法。我总是感到困惑。首先,将所有内容作为引用传递似乎是一致的,但是不可能将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;
}
由于 阿贾伊
答案 0 :(得分:25)
参考文献更容易正确。
你的文字问题是你没有使用const引用吗?您不能将临时(由文字生成)绑定到非const引用,因为更改它是没有意义的。您可以将一个绑定到const引用。
特别是,当一个参数传递给一个函数,并且该函数不会改变它,并且它不是一个内置类型时,传递const引用。它与pass by value非常相似,除了它不需要复制构造函数调用。
指针非常有用,因为它们具有可以测试的无效值。有时这是无关紧要的,有时它非常重要。当然,你通常不能通过指针传递文字,除非(如果是字符串文字)它已经是。
某些编码标准表示非const引用不应该传递任何内容,因为它在调用时没有提供参数可能被函数更改的指示。在这种情况下,您将被要求通过指针。我不赞成这一点,特别是因为编程工具使得获取函数签名变得更容易和容易,因此您可以查看函数是否可以更改参数。但是,在组或企业中工作时,样式一致性比任何单个样式元素都重要。
答案 1 :(得分:23)
一个好的经验法则:“在必要时使用引用,必要时使用指针”。
答案 2 :(得分:6)
在我之前的工作中,我们的规则是普通的参考文献实际上从未使用过。相反,我们同意:
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)形式。