我一直关注此tutorial,我无法理解这一部分。
所以它说传递值会创建数据的副本,因此它可能是无效的,因为它创建了数据的副本,这是有道理的:
string concatenate (string a, string b)
{
return a+b;
}
然后你有了这个,以解决创建数据副本的问题。问题:
string concatenate (string& a, string& b)
{
return a+b;
}
这是有道理的,因为它使用了引用。
但我不明白:
string concatenate (const string& a, const string& b)
{
return a+b;
}
其中说:
通过将它们限定为const,该函数被禁止修改a和b的值,但实际上可以作为引用(参数的别名)访问它们的值,而不必制作字符串的实际副本。
为什么不使用第二种方式?在这个例子中,无论如何都没有修改数据?有人能给我一个更好的例子吗?
是出于安全原因这么做了吗?
答案 0 :(得分:2)
如果你实际拥有的字符串是const,或者你只有const引用它们,那么你可以将它们传递给这个函数:
string concatenate (const string& a, const string& b);
但是你无法将它们传递给这个函数:
string concatenate (string& a, string& b);
如果您的字符串不是 const,那么无论如何都可以将它们传递给任一函数。因此,除了确保您不会无意中修改字符串之外,参数上的const
允许更通用的函数,它可以接受const或非const参数。
例如:
string concatenate_non_const (string& a, string& b)
{
return a+b;
}
string concatenate_const (const string& a, const string& b)
{
return a+b;
}
int main()
{
std::string s1 = "hello";
std::string s2 = "world";
const std::string cs1 = "hello";
const std::string cs2 = "world";
concatenate_const(s1, s2); // okay
concatenate_const(cs1, cs2); // okay
concatenate_non_const(s1, s2); // okay
concatenate_non_const(cs1, cs2); // error
}
此外,除了声明为const的对象外,还有一些时间要考虑,不能绑定到非const引用。
concatenate_const("hello", "world"); // okay
concatenate_non_const("hello", "world"); // error
答案 1 :(得分:1)
为什么不使用第二种方式?在这个例子中,无论如何都没有修改数据?有人能给我一个更好的例子吗?
在你的情况下,在你编写函数的地方,这并不重要,因为你自己并没有改变参数。
更好的示例
使用const
引用引用的更好示例是使用交换函数。以此为例,交换2个整数。
void swap(int& a, int& b)
{
int temp = a;
a = b;
b = temp;
}
现在,在上面的示例中,您无法使用const
引用,因为a
和b
的分配符合修改条件。在上面这样的函数中,引用非常有用,const
替代方法不起作用。
不太具体的例子
这是一个不太具体的例子,它说明了与swap(a,b)
函数相同的概念:
void pre_incr(int& a)
{
++a;
}
现在这个函数没有swap()
那么具体的原因是,你可以像这样使用pass by value:
void pre_incr(int a)
{
return ++a;
}
无论哪种方式,这两个函数都说明了传递const
引用和传递正常引用之间的区别,并且还传递了值。
答案 2 :(得分:0)
是出于安全原因这么做了吗?
构成编程语言的大部分内容都是“安全原因”,否则我们可能会像代码那样在汇编中跳转标签。
使函数的参数引用const字符串有两个目的:
考虑这种情况:
string a = "foo", b = "bar";
cout << concatenate(a, b); // "foobar"
你得到你所期望的,即使,如果你修改了串联函数中传递的字符串。
string a = "foo", b = "bar";
cout << concatenate(a, b);
// some code
string c = "baz";
cout << concatenate(a, c); // "Aaaabaz"
在考虑调查a
之前,您可能会搜索所有“某些代码”来查找对concatenate
的修改...
另请注意,第一个示例(单次使用参数字符串)是您在concatenate
的单元测试中可能会找到的。
答案 3 :(得分:-1)
当你在第一个方法中传递一个字符串时没有const而没有&amp;它需要被复制到效率低下的函数中。传递引用时,不会复制它。当你通过const引用时,它避免了复制的低效率,同时不允许函数修改字符串。