我有这段代码:
#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<>
事物。但第一个有效,而第二个有效。为什么这样?
答案 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;