提问者:小点点

c当const不是显式的时?


我在互联网和StackOverflow上搜索了const_cast

考虑到这段代码,

#include <iostream>
using namespace std;

int main(void)
{
    const int a = 1;
    int *p = const_cast<int*>(&a);
    *p = 2;

    cout << "value a="<< a << endl;
    cout << "value *p=" <<*p << endl;
    cout << "address a=" <<&a << endl;
    cout << "address p=" <<p << endl;
}

输出为:

value a=1
value*p=2
地址a=0x69fef8
地址p=0x69fef8

我发现这样的代码可能会导致未定义的行为。(例如编译器可能会将所有a替换为1以进行优化,因此强制转换没有意义)

我还发现了这句话:

如果您放弃已显式声明为const的对象的一致性,并尝试修改它,则结果是未定义的。

但是,如果您放弃未显式声明为const的对象的一致性,则可以安全地修改它。

还有这个:

请注意,C提供了const_cast来删除或添加变量的恒定性。但是,在删除恒定性时,它应该用于删除指向最初不是常量的引用/指针的恒定性。

现在,考虑对上面的代码进行以下修改:

int b = 1;
const int a = b;

输出为:

value a=2
value*p=2
地址a=0x69fef4
地址p=0x69fef4

我明白:

int a=1中的a是在编译时处理的常量表达式。
int a=b中的a不是,只能在运行时处理。

如此处所述。

我的问题:

const声明什么时候是显式的,什么时候不是?它最初怎么可能是非const的?


共2个答案

匿名用户

一个有效的简单反例:

void foo(const int *a) {            // Pointer-to-const here
    int *p = const_cast<int*>(a);
    *p = 2;
}

int main() {
    int a = 1;                      // But underlying object is not const
    foo(&a);
}

匿名用户

在此示例中:

int b = 1;
const int a = b;

a是顶级const,而b不是。

如果你要将它们传递给这样的函数:

void f(const int &i){
    const_cast<int &>(i)++;
}

然后f(a)是非法的,因为您正在更改一个顶级const对象,一个从一开始就声明为const的对象,因此您的程序将表现出未定义的行为。
另一方面,f(b)会很好,因为b一开始不是const,然后通过参数转换添加了一个const,然后再次删除了const。由于b开始是可修改的,您可以通过删除添加的const来修改它。

相关问题