【问题标题】:Why is it Legal to Change a const value using const_cast in C++ [duplicate]为什么在 C++ 中使用 const_cast 更改 const 值是合法的 [重复]
【发布时间】:2021-05-16 07:10:54
【问题描述】:

您好,我正在尝试理解 C++ 中的显式转换,因此通过创建不同的示例来玩弄。下面我给出一个我认为应该是非法的示例,因为它会更改 const 对象的值。

const char t='a';
const char *pc=&t;
char *p = const_cast<char*>(pc);
std::cout<<"Before changing t "<<*pc<<std::endl;
*p='c';
std::cout<<"After channging t: "<<*pc<<std::endl;

执行程序后,对象 t 的值成功更改为 c,正如我在控制台中看到的那样。我的问题如下:

  1. 这不应该是非法的吗,因为拥有一个 const 对象的全部意义在于它不能被更改。
  2. 拥有这个 const_cast 有什么需要,在我看来,从某种意义上说,我们正在更改 const 对象是很危险的。
  3. 像这样使用 const_cast 完全可以吗?再说一次,如果不是,那么我应该什么时候使用它?

【问题讨论】:

  • 非法的。如果你抢劫了某人并且没有被抓到,那么抢劫是否合法?
  • 参见this question 以了解const_cast有效用法。
  • 如果你输出t的值而不是*pc的值,你可能会发现它的值实际上并没有改变。 Example
  • 是的,为什么当 t 为 const 时 *pc 与 t 不同?我还检查了 t 是非 const 的情况。在这种情况下,t 的值实际上与 const 情况不同。我认为这可能是因为创建了一个临时变量。
  • 编译器允许您在无需诊断 (NDR) 的情况下编写未定义行为 (UB) 的原因是因为一般情况可能难以确定代码何时会遇到 UB。其中“困难”在于“我们还没有解决停机问题”。

标签: c++ c++11 casting type-conversion constants


【解决方案1】:

为什么在 C++ 中使用 const_cast 更改 const 值是合法的

为什么你认为“在 C++ 中使用 const_cast 更改 const 值是合法的”,你说的 “合法更改”是什么意思? p>

(†) const 对象的值不能更改。尝试修改 const 对象的行为未定义。

  1. 拥有这个 const_cast 有什么需要

有时你有一个非常量对象的常量引用,并且你想修改那个非常量对象。这些情况很少见,因此很少需要 const_cast。

其他时候你的函数接受指向非常量的指针但永远不会修改指向的对象。您可以 const_cast 使用指向 const 的指针调用此类函数。在使用古老的 C 库时,有时可能会遇到这种情况。小心不要错误地假设“从不修改指向的对象”。

  1. 这样使用 const_cast 完全没问题吗?

未定义行为 (UB) 并不完全正常。这完全是坏事。不要这样做。


当 t 为 const 时,为什么 *pc 与 t 不同?

看起来可能是这样,因为程序的行为是未定义的。

那么它依赖于编译器吗?

UB 可以依赖于编译器。它还可以取决于系统库、CPU 内核数量和月相。对于任何条件的任何组合,都不能保证行为相同。也不能保证行为会有所不同。对这种行为没有任何保证。

我们是否可以使用 const_cast 改变 const 的值?

参见上面的 (†)。

【讨论】:

  • 大声笑,你忘了说行星的运动了!
  • @JasonLiam 它包含在 "any" 中:)
【解决方案2】:

这不应该是非法的吗,因为拥有一个 const 对象的全部意义在于它不能被更改。

C++ 使用术语“未定义的行为”。这是未定义的行为,因为正如您所说,tconst 对象。

拥有这个 const_cast 有什么需要,在我看来,从我们正在更改 const 对象的意义上来说,这是很危险的。

它适用于引用非 const 对象const 变量

考虑您的代码的这种变体。

char t='a'; // No longer a const char!
const char *pc=&t;
char *p = const_cast<char*>(pc);

这里,pc 是一个“指向const char 的指针”,但它恰好指向一个不是 constchar

在这种情况下,代码是有效的。字符t可以改变,而指针pc不能用来修改。

像这样使用 const_cast 完全没问题吗?

不是你使用它的方式。见上文。

【讨论】:

  • 我明白你做了什么,因为我已经事先检查了那个案例(你给的)。我知道它是在这种情况下定义的行为,而 const_cast 就是为此而设计的。但问题是如果变量 t 是非常量,为什么不直接改变它呢?我们可以只说 t='c' 而不是使用 const_cast。
  • @JasonLiam why not directly change the variable t if it is nonconst? 因为它是一个简化的例子。预期的假设是使用 const_cast 的上下文没有也不能访问t
  • @JasonLiam 那么你可能会问“为什么编译器让我这样做?”,而不是“为什么它是合法的?”是这样吗?
  • 那么它是否依赖于编译器,我们是否可以使用 const_cast 更改 const 的值?
  • @JasonLiam 一些人已经告诉你它已经是什么了。我怀疑你会从学习未定义行为的含义中受益。没有人可以为您定义未定义的行为将如何表现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-27
  • 2011-03-29
  • 2013-03-07
  • 1970-01-01
  • 2020-07-11
  • 2014-01-03
  • 1970-01-01
相关资源
最近更新 更多