【发布时间】:2020-10-04 23:32:57
【问题描述】:
考虑以下代码:
#include <iostream>
void f(int const& a, int& b)
{
b = a+1;
}
int main() {
int c=2;
f(c,c);
std::cout << c << std::endl;
}
- 函数
f采用两个引用参数:int const& a和int& b。因此,f应该不会修改a,但它可以修改b,而且确实可以。 - 但是,在
main中,我传递了 same 变量,a和b引用了 both。由于f修改了b,它也修改了a,它不应该这样做
此代码在没有任何警告的情况下编译并打印3。如果我们单独跟踪每个变量,看起来 const 正确性受到尊重:c 是非常量的,因此将它作为 const 引用传递为 a 以及作为非常量传递是完全可以的引用为b,在f 的主体内,我们修改b,它是非常量的,而不涉及a,它是const。然而,当c 同时用作a 和b 时,a 在f 的主体内被修改,违反a 是const 的假设,即使没有明确的const_cast曾经调用过。
我尽可能简单地制作了这个示例,但人们很容易想到不那么明显的用例(例如作用于非常量引用参数的const 方法)。
我的问题是:
- 我们真的可以说上面的代码是 const 正确的吗?
- 上述用例是已知模式吗?这被认为是不好的做法吗?
- 除了让读者感到困惑之外,上面的代码是否会成为技术问题的根源?例如未定义的行为,或者编译器执行错误的简化假设?
【问题讨论】:
-
如果使用返回值而不是引用参数会怎样?
c = f(c);会不会看起来很奇怪? -
我的猜测:对于
f(),const的正确性是可以的。它履行了它的承诺:不修改a并修改b。滥用发生在main()(对a和b使用相同的变量)。你还能做什么:签入f()那个&a != &b和/或评论一个响应。文档中的约束。f()(如有必要)。 -
@FredLarson 会有所不同。在我的示例中,我有一个
const变量正在修改within函数。在b = a+1;之后,a的值发生了变化。我可以将打印内容放在f中,以使我的担忧更加明显 -
我认为教训是返回值比输出参数更清晰。更喜欢他们。
-
回答您的问题:是的。是的。是的,不如使用返回值。对程序员来说是的;不适合编译器。没有和没有。
标签: c++ pass-by-reference const-correctness pass-by-const-reference