与const和non-const相同的对象,我应该假设什么行为正确

Same object as const and non-const, what should I assume to behave correctly?

本文关键字:什么 假设 我应该 对象 const non-const      更新时间:2023-10-16

我有一个形式的函数

return_type function(const argument_type & a, argument_type & b);

如果传递了与ab相同的对象,我可以继续执行该函数(从而可能对其进行修改)还是停止?

我不知道编译器的假设是如何在这种情况下传播的。

我的猜测是,将其作为非常量b传递的非常量假设应该足够并允许修改,但这只是猜测。


大多数答案都是关于能够修改ab,或调用非常量方法。我知道,如果我传递与constnon-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){/*...*/;} // ??? 

我发现的最相似的问题(但不是真的)

通过指向self-的非常量指针修改const方法中的self-

的问题

return_type function(const argument_type & a, argument_type & b);

调用CCD_ 8是函数可能是

  • 通过形式参数b修改对象,而

  • 同时期望形式参数CCD_ 10保持不变。

因此,您可能会破坏函数的假设,导致例如错误的结果或崩溃。


有一个函数在设计时经常具有这种签名,即复制赋值运算符。它的常量形式参数a是显式提供的参数,而它的可变形式参数(如果可以这样称呼的话)是隐式*this。它可以检查自引用(参数的别名),也可以复制和交换。


总之,是否可以安全地使用与参数a和参数b相同的对象调用函数取决于函数,但很可能会违反函数的假设,即形式参数引用不同对象是隐含的先决条件。

您可以决定是否可以用两次给定的相同参数调用该函数
无论如何,你不应该试图确定你是否两次得到同一个对象,只要你的算法的正确性不取决于它,或者你没有保证。

它们在运行时以完全相同的方式传递,相同的引用/指针指向完全相同的东西。

const的区别仅发生在编译时。编译器将确保您只调用const方法,而不是试图修改此const对象的属性,否则会引发编译错误,因为您不应该修改它。

我的猜测是,将其作为非常量b传递的非常量假设应该足够并允许修改,但这只是猜测。

是的,function可以通过b调用非const方法,但不能通过a调用。

直观地说,这意味着如果相同的对象也通过非const引用b传入,则function可以更改通过const引用a传入的对象。

通常,const只保证可以或不能对const变量执行什么操作。可能还有其他变量引用const变量,或者引用其中的对象,使const变量能够被一个看起来不像是在修改const变量的函数修改。

回到您的案例,这取决于比function更高级别的函数和类,它们自己对使用const参数、成员函数等可以修改和不能修改的内容实施约束。