为什么const_cast删除指针的constness而不是指向const的指针?

Rah*_*hul 13 c++ const-cast

我理解它const_cast适用于指针和引用.

我假设输入const_cast应该是指针或引用.我想知道为什么如果输入是一个指针/引用,它不会删除constness const int

以下代码按预期工作.

  1. const_cast 多级指针

    int main()
    {
        using std::cout;
        #define endl '\n'
        const int * ip = new int(123);
        const int * ptr = ip;
        *const_cast<int*>(ptr) = 321;
        cout << "*ip: " << *ip << endl;  // value of *ip is changed to 321
    }
    
    Run Code Online (Sandbox Code Playgroud)

    但是当我尝试指向const int或引用时const int,该值似乎没有改变.

  2. const_cast 参考const int

    int main()
    {
        using std::cout;
        #define endl '\n'
        const int i = 123;
        const int & ri = i;
        const_cast<int&>(ri) = 321;
        cout << "i: " << i << endl;  // value in 'i' is 123
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. const_cast 用指向const int的指针

    int main()
    {
        using std::cout;
        #define endl '\n'
        const int i = 123;
        const int * ri = &i;
        *const_cast<int*>(ri) = 321;
        cout << "i: " << i << endl;  // value in 'i' is 123
    }
    
    Run Code Online (Sandbox Code Playgroud)

(1)按预期工作,但我无法理解为什么(2)(3)不按照我的想法工作,尽管输入const_cast是指针/参考.

请帮助我理解这背后的哲学.谢谢.

n. *_* m. 19

常量有两种.

对象的常量是对象的固有属性.它无法改变.

想想印刷书籍中的页面.它可以被视为一串字符,并且无法更改.它说它说什么,就是这样.所以这是一个const string.

现在想起一块黑板.它可能有一些东西写在上面.你可以擦掉它并写下别的东西.所以黑板是非常规的string.

另一种常量是指针和引用常量.这个constness不是指向对象的固有属性,而是权限.它表示不允许通过此指针修改对象.它没有说明是否可以修改对象本身.

因此,如果你有一个const指针,你不一定知道它指向的是什么.也许这是一本书页.也许这是一块黑板.指针不告诉.

现在,如果你确实知道它确实是一块黑板,你可能会讨厌,并要求允许继续并改变它上面的内容.这就是const_cast的作用.它允许你做某事.

如果您要求修改字符串的权限会发生什么,结果是打印页面?你得到了你的许可,你继续擦拭它......并且......究竟发生了什么是未定义的.也许什么都没有.也许印刷品被涂抹了,你既不能识别原始字符串也不能在上面写任何东西.也许你的世界爆炸成碎片.你可以试试看,但不能保证明天会发生同样的事情.


gez*_*eza 14

(2)和(3)具有相同的原理,所以我只谈(2).

这条线

const_cast<int&>(ri) = 321;
Run Code Online (Sandbox Code Playgroud)

有未定义的行为.

您无法const根据标准修改对象,甚至不能修改对象const_cast.如果const从指针/引用中删除并修改指向/引用的对象,则必须首先将指向/引用的对象声明为const.

const_cast应该只使用,当你有一个const指针由于某种原因,并且你知道某些东西没有被声明为const.

  • 另一个用例是与API(通常是早期的C)进行互操作,这些API不会修改对象,但不是const正确的. (2认同)