CPP const函数参数说明

时间:2016-09-10 18:27:14

标签: c++

我一直关注此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的值,但实际上可以作为引用(参数的别名)访问它们的值,而不必制作字符串的实际副本。

为什么不使用第二种方式?在这个例子中,无论如何都没有修改数据?有人能给我一个更好的例子吗?

是出于安全原因这么做了吗?

4 个答案:

答案 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引用,因为ab的分配符合修改条件。在上面这样的函数中,引用非常有用,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引用时,它避免了复制的低效率,同时不允许函数修改字符串。