与 const 和非常量相同的对象,我应该假设什么行为正确?
-
20-12-2019 - |
题
我有一个形式的函数
return_type function(const argument_type & a, argument_type & b);
如果相同的对象被传递为 a
和 b
, ,我可以继续执行该函数(从而可能对其进行修改)还是停止?
我不知道编译器假设如何在这种情况下传播。
我的猜测是,它作为非常量传递的非常量假设 b
应该足够并允许修改,但这是一个猜测。
大多数答案都是关于 有能力的 修改 a
或者 b
, ,或调用非常量方法。我知道如果我传递同一个对象 const
和 non-const
我能做到。我的疑问更多地在于函数返回时我将离开程序,以及它是否可以阻止一些编译器假设,例如:
class A(){
int value;
}
void function1(const A & arg1);
void function2(A & arg1);
void function3(const A & arg1, A & arg2);
A a;
a.value=5;
function1(a);
if(a.value==5){/*...*/;} // the if can be optimized out to true, because [a] was const
a.value=5;
function2(a);
if(a.value==5){/*...*/;} //must be checked, [a] could have been modified
a.value=5;
function3(a, a);
if(a.value==5){/*...*/;} // ???
我发现的最相似的问题(但不是真的)
解决方案
问题在于
return_type function(const argument_type & a, argument_type & b);
和一个电话 function( o , o )
这个函数可能是
通过形式论证修改对象
b
, , 尽管同时期待正式辩论
a
保持不变。
所以你可能会打破函数的假设,导致例如结果不正确或崩溃。
有一个函数是 按设计 经常有这种签名,即复制赋值运算符。它不断的形式论证 a
是显式提供的参数,其可变的形式参数(如果可以这样称呼它)是隐式的 *this
. 。它可以检查自引用(参数的别名),也可以复制和交换。
总之,是否可以安全地调用具有相同对象作为参数的函数 a
并作为参数 b
取决于函数,但您很可能会违反函数的假设,即它有一个隐含的前提条件,即形式参数引用不同的对象。
其他提示
您决定是否可以使用给定两次的相同参数来调用该函数。
无论如何,您不应该尝试确定是否两次获得相同的对象,只要您的算法的正确性不依赖于它或者您不提供任何保证。
它们在运行时以完全相同的方式传递,相同的引用/指针指向完全相同的事物。
与的区别 const
仅在编译时发生。编译器将确保您仅调用 const
方法并且不尝试修改 this 的属性 const
对象,否则会抛出编译错误,因为您不应该修改它。
我的猜测是,将其作为非常量 b 传递的非常量假设应该足够并允许修改,但这是一个猜测。
是的, function
可以调用非const
方法通过 b
但不是通过 a
.
直观上来说,这意味着 function
可以改变通过传入的对象 const
参考 a
如果相同的对象也通过非const
参考 b
.
一般来说, const
仅保证您可以做什么或不能做什么 const
多变的。可能还有其他变量引用 const
变量,或者其中的对象,可以启用 const
要由看起来不像正在修改的函数修改的变量 const
多变的。
回到你的例子,这取决于比你的更高级别的函数和类 function
对自己强制限制什么可以修改,什么不能修改 const
参数、成员函数等