我有一个返回如下数组的函数:
vector<string> GetString()
{
vector<string> s;
s.push_back("one");
s.push_back("two");
s.push_back("three");
return s;
}
我以这种方式称呼它:
vector<string> mystrings=GetStrings();
我也可以按如下方式实现:
void GetString(vector<string> & s)
{
s.push_back("one");
s.push_back("two");
s.push_back("three");
}
并以这种方式调用它:
vector<string> mystrings;
GetStrings(mystrings);
哪一个更好?
版本1是否将矢量复制到另一个?如果是,那么如果向量很大则它很慢。
答案 0 :(得分:17)
哪一个更好?
他们做不同的事情。如果你想要一个只包含那些字符串的向量,请使用第一个;如果您希望能够将这些字符串附加到现有向量,请使用第二个。
如果你想要第一个版本的语义,那么就更容易正确使用并且更难以错误地使用,这是“更好”。
版本1是否将矢量复制到另一个?
在现代C ++中,绝对不是:返回局部变量并从临时初始化都是通过移动而不是复制来完成的。即使你坚持使用前C ++ 11编译器,也应该省略这两个副本。如果你的编译器不支持移动语义或复制省略,那么你真的应该把它扔掉。
答案 1 :(得分:2)
这在很大程度上是个人偏好的问题,无论您需要使用哪种编码约定。
在C ++ 11之前,第二种方法有时被认为是更可取的。性能保证良好,因为没有不必要的复制。另一方面,第一种方法有可能(理论上)调用相当昂贵的复制构造函数。
在实践中,称为复制省略的优化通常会避免复制构造函数,这意味着无论哪种方式,性能都是一样好。但这并不能保证,因为它可能取决于编译器设置/功能等因素。
C ++ 11引入了移动语义。它提供了一种消除复制的替代方法,并且内置于语言规范中(而不是可选的编译器优化)。从可读性的角度来看,这可以使第一个选项变得更好,因为它可能更清楚你的代码在做什么。