C++中更改常量值的方法

7

const value经常在编程中使用。它能够为程序员提供保障,即该值将来不会改变。然而,这并没有得到完全的执行。因此,有时会导致微妙的错误,这些错误非常难以解决。例如:

int a = 1;
const int& b = a; // I promise I will not change
a = 3; // I am a liar, I am now 3
cout << b; // As I will now show 3

有时候我们也可以通过其他方式来更改const常量的值。其中一些方式相当复杂,需要大量的代码,而这些代码往往会在其他代码段中丢失,从而导致错误。

那么有人能详细介绍一下更改const value的可能方式吗?如果你不知道所有方式也不用担心(包括我自己),只要告诉我们你所了解的所有方式就可以了!毕竟我们只能给出我们所掌握的内容!


8
a = 3并不是谎言,因为a是非常量变量。而const_cast<int&>(b) = 3;则是谎言。 - James Adkison
8
“b”并没有承诺该值不会改变。强制执行的是您不能直接使用“const”引用更改该值。我认为这是一个有趣的问题,但是您的例子肯定不是最好的。 - 463035818_is_not_a_number
2
但是这个例子不是有问题吗?因为你把b声明为常量而不是a,如果你执行b=3,那么它将无法编译。 - EdChum
3
顺便说一下,如果一个非const的整数不能更改其值,只因为您将其作为const引用传递,那将是相当奇怪的。这就像假设人们不允许成长,只因为他们护照上给出的身高没有改变。虽然这不是最好的比喻,但足够接近了 ;) - 463035818_is_not_a_number
@tobi303 这是一个相当好的比喻。我知道我的例子不是最好的,甚至可能不是很好。重点是b的值确实改变了。这使得假设b不会改变无效。我知道我以一种糟糕的方式滥用了漏洞。这确实导致了一个微妙的错误。 - Existent
显示剩余4条评论
6个回答

9
const int& b = a; // I only promise I will not change the value via b, nothing more.

const并不能保证值不会被其他引用或指针更改。来看一下下面的代码:

void f(const int& b) { ... }
...
int a = ...;
f(a);
a = ...;

f()函数内传入的参数不会改变a的值,这是唯一的保证。

const只是一个帮助器。如果你不打算改变某个值,请将其声明为const,编译器会帮助你检查。但你仍然可以像你的代码所示那样以其他方式更改原始值,这仍然是你的责任。


2

是的,const_cast可以用于去除“const”关键字的影响(但并非总是如此)。例如:

    int a= 1;
    const int& b = a;
    a = 3;
    std::cout<<b<<std::endl;
    const_cast<int&>(b) = 4;
    std::cout<<b<<std::endl;

参考:http://en.cppreference.com/w/cpp/language/const_cast

const_cast是一个类型转换运算符,用于将常量变量的const属性去除。它可以用来修改指向常量的指针或引用,以便可以修改底层对象的值。但要注意,如果试图修改常量对象本身的值,其行为未定义。


2
 int a=1;
   const int *b=&a;
    a=3;
   cout<<(*b);
   return 0;

1

如果不引起未定义的行为,就无法更改const值。

编译器不会为您确定const和非const值之间的区别。它依赖于您,即程序员,通过类型系统来通知它。名称是const还是non-const,编译器在名称上强制实施constness,而不是在值上。

有时候似乎可以修改const值,例如当该值引用其他值并修改该值时。第一直觉认为这些情况不应该这样行事,但一旦您真正理解和考虑const正确性,您会发现它非常一致。


1
int k = 0;
const int *l = &k;
cout<<*l; // 0
k=1;
cout<<*l; // 1

这里我只声明了一个变量为 constant,即 l。因此,变量 l 不能再被改变。然后我将 l 赋值为 k 的地址;

但现在我可以在任何地方更改 k 的值,并且这将反映在 l 中,因为它们共享相同的内存。


1

您需要首先将一个const变量用作指针,然后使用const_cast<数据类型>()语句,如下所示:

使用命名空间std;

int main()
{

    const int *i = new int(0);
    int *n = const_cast<int*>(i);

    *n = 10;
    cout << *n << endl << *i << endl;
    return 0;
}

输出将会是:

10
10

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接