【问题标题】:C++ modifying const object through const_cast pointer works [duplicate]C ++通过const_cast指针修改const对象有效[重复]
【发布时间】:2015-01-11 13:13:08
【问题描述】:

我有这段代码:

#include <iostream>    
using namespace std;

class X {

    public:
        const int x;
        X(int i) : x(i) {  }            
        int getX() const { return x; }           
};

int main()
{
      const X d(45);

      const_cast<X *>(&d)->x = 47;
      cout << d.getX() << endl;

      const int j = 3; // j is declared const
      int* pj = const_cast<int*>(&j);
      *pj = 4; 
      cout << *pj << endl; //should not work, like above

      return 0;
}

正如我发现的here即使 const_cast 可以从任何指针或引用中删除 const 或易变性,使用生成的指针或引用来写入声明为 const 的对象或访问已声明的对象volatile 调用未定义的行为。 他们甚至继续提供下面的示例,即我给出的第二个示例,说明它应该给出未定义的行为。

但是,在编译代码并运行 (here) 时,第二个没有错误,并且始终打印出 4。而第一个抛出错误:

assignment of read-only member 'X::x'                            
       const_cast<X *>(&d)->x = 47;

当然,从X 中的x 声明中删除const 可以使其正常工作。但是,它也与第一个具有相同类型的恶作剧,在转换 const_ptr&lt;&gt; 后通过指针更改 const 事物。但是第一个有效,而第二个无效。为什么会这样?

【问题讨论】:

  • “未定义的行为”!=“必须崩溃”。此外,它通常意味着“工作时没有明显的问题迹象”。
  • 那么,我得到的4 是未定义的行为?我不应该得到它?
  • “未定义”表示该标准没有就程序应该做什么提供任何指导。这并不意味着您可以观察到任何奇怪的东西或收到错误消息。
  • @Cupidvogel:是的,获得4 是未定义行为的一种可能实例。询问“应该”做什么未定义的行为是没有意义的。
  • 是的,是的,我就是这么说的,所以 4 始终作为答案是未定义的一部分,并且不能保证,对吗?

标签: c++ pointers constants const-correctness const-cast


【解决方案1】:

两者都需要未定义的行为,不幸的是,这可能意味着工作有时。

   int* pj = const_cast<int*>(&j);
   *pj = 4; 

此外,并非所有编译器都足够聪明,可以找出这种间接操作。

【讨论】:

    【解决方案2】:

    将除实际 const ptr* 之外的任何内容进行 const 转换可能是一个糟糕的主意,即使它在大多数情况下确实有效。

    话虽如此,您的代码无法正确编译的原因很简单:您删除了 X 对象的常量,但您没有同时删除您尝试修改的 x 成员的常量。

    试试这个:

    *const_cast<int*>(&(const_cast<X*>(&d)->x)) = 47;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-31
      • 1970-01-01
      • 2019-09-22
      • 2014-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多