制作由值常量传递的参数有什么意义?

What is the point of making an argument that is passed by value constant?

提问人:24n8 提问时间:12/18/2018 更新时间:12/19/2018 访问量:823

问:

这更像是一个一般性的问题: 如果函数参数是按值传递的,那么创建函数参数有什么意义吗?const

在我正在学习的代码中,我看到了很多以下内容:

void some_function(const std::vector<double> some_vec);

std::vector是按值传递的,那么 的意义何在呢?const

就像我会理解该函数是否通过引用传递向量一样:

void some_function(const std::vector<double> &some_vec);

但我认为前者毫无意义。const

C++ 常量 按值传递

评论

0赞 Matthieu Brucher 12/18/2018
请参阅 softwareengineering.stackexchange.com/questions/204500/...
0赞 StoryTeller - Unslander Monica 12/18/2018
不同的问题(明确询问原语),但相关的答案 stackoverflow.com/questions/46292490/......
0赞 Daniel Langr 12/18/2018
如果编译器知道某些内容是恒定的,它就可以使用此信息,并可能通过优化实现更高的程序效率(并且还可以防止您意外修改该对象)。但是,在函数声明中设置按值传递的参数是没有意义的。相反,它在函数定义中确实如此。const
0赞 24n8 12/18/2018
@DanielLangr 当你说“但是,在函数声明中设置按值传递的参数 const 是没有意义的。相反,它在函数定义中确实如此。我以为函数声明原型必须与其各自的声明相匹配?就像你用参数做一个声明,那么你的函数定义也必须用于参数?constconst
0赞 Daniel Langr 12/18/2018
@Iamanon 你看过StoryTeller链接的问题吗?即他的回答:stackoverflow.com/a/46292715/580083

答:

5赞 Bathsheba 12/18/2018 #1

特别是在处理数学代码时,它可能非常有用,因为它可以阻止错误的重构器更改作为函数参数传入的变量。例如,你不想弄乱 pi 的值(令人讨厌的是,它不是 C++ 标准的一部分),或者引力常数之类的东西,&c。

过去,我看到代码是由一位物理学家编写的,他确信圆周率应该比大多数人认为的要大两倍。pi *= 2;

在函数声明和定义中匹配限定符也很好(尽管语言本身并不坚持这一点)。

诚然,我不怎么使用它。

评论

0赞 StoryTeller - Unslander Monica 12/18/2018
不过,在纯粹的声明中?
0赞 Bathsheba 12/18/2018
@StoryTeller:我认为如果声明和定义匹配是件好事,当然有些人会持相反的观点,尤其是在参数方面。const
2赞 StoryTeller - Unslander Monica 12/18/2018
我呃......回答这个问题时感觉不舒服
2赞 Bathsheba 12/18/2018
@StoryTeller:噢,但你应该!普朗克常数呢?
2赞 NathanOliver 12/18/2018
我喜欢普朗克常数。我认为它比阿伏伽德罗的数字;)要好
5赞 Walter 12/18/2018 #2

关键是要防止函数体更改值。函数参数只是函数体中的一个自动变量,您可能希望确保它保持在其输入值。考虑

int foo(int x)
{
    /* lots of code */
    some_other_func(x);  // may modify x
    /* even more code */
    return x+42;         // x may have been modified
}

int foo(const int x)
{
    /* lots of code */
    some_other_func(x);  // will not compile if x is taken by non-const reference
    /* even more code */
    return x+42;         // x is guaranteed at its input value
}

根据经验,声明所有不打算更改的内容。然后,如果您或某人不小心尝试更改此类变量,则会导致编译时错误。const

还要注意的是,声明器在函数声明中没有作用,而只在函数定义中起作用,即以下内容是完全可以的(实际上推荐):const

struct bar
{
   int foo(int) const;
   /* more code */
};

int bar::foo(const int x) const // possibly in another compilation unit
{
   ...
}