C ++通过const_cast指针修改const对象

时间:2015-01-11 13:13:08

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

我有这段代码:

#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可以从任何指针或引用中删除constness或volatile,使用结果指针或引用来写入声明为const的对象或访问一个对象被声明为volatile会调用未定义的行为。他们甚至会继续提供下面的示例,我给出的第二个示例,声明它应该给出未定义的行为。

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

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

当然,从const中的x声明中移除X可以使其正常工作。但是,它也与第一个相同类型的恶作剧,在投射const之后通过指针改变const_ptr<>事物。但第一个有效,而第二个有效。为什么这样?

2 个答案:

答案 0 :(得分:1)

两者都要求未定义的行为,有时可能意味着正在工作

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

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

答案 1 :(得分:0)

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

话虽如此,您的代码无法正确编译的原因非常简单:删除X对象的常量,但是您也无法删除您尝试修改的x成员的常量。 / p>

试试这个:

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