为什么const_cast删除指针的恒常性,而不删除指向常量的指针的恒常性?
Why does const_cast remove constness for a pointer but not for a pointer to a const?
我知道const_cast
可以使用指针和引用。
我假设const_cast
的输入应该是指针或引用。我想知道如果输入是对const int
的指针/引用,为什么它不会删除恒常性?
以下代码按预期工作。
-
使用多级指针
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 }
但是当我尝试指向
const int
的指针或指向const int
的引用时,该值似乎没有改变。 -
const_cast
参考常量 intint 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 }
-
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 }
(1( 按预期工作,但我无法理解为什么 (2( 和(3(没有按照我想象的方式工作,尽管对const_cast
的输入是指针/引用。
请帮助我理解这背后的哲学。谢谢。
有两种恒常性。
对象的恒定性是对象的固有属性。它无法更改。
想想印刷书籍中的一页。它可以被视为一串字符,并且无法更改。它说了它所说的,仅此而已。所以这是一个const string
.
现在想想黑板。上面可能写着什么。你可以擦掉它并写一些别的东西。所以黑板是一个非常量string
.
另一种常恒定性是指针恒常性和引用恒常性。这种恒定性不是指向对象的固有属性,而是一种许可。它说你不允许通过这个指针修改对象。它没有说明对象本身是否可以修改。
因此,如果你有一个常量指针,你不一定知道它真正指向什么。也许是一本书的页面。也许是一块黑板。指针不告诉。
现在,如果您以某种方式知道它确实是一块黑板,您可能会感到讨厌并要求允许继续更改上面写的内容。这就是const_cast所做的。它允许你做某事。
如果您要求修改字符串的权限,结果是打印页面,会发生什么情况?你得到你的许可,你继续擦拭它...和。。。究竟发生了什么是不确定的。也许什么都没有。也许印刷品被涂抹了,你既不能识别原始字符串,也不能在上面写任何东西。也许你的世界会爆炸成碎片。你可以试着看看,但不能保证明天也会发生同样的事情。
(2(和(3(具有相同的原理,所以我只讨论(2(。
该行
const_cast<int&>(ri) = 321;
具有未定义的行为。
您不能根据标准修改const
对象,即使使用const_cast
也不能。如果从指针/引用中删除const
,并修改指向/引用的对象,则不得首先将指向/引用的对象声明为const
。
const_cast
应该只在当您出于某种原因有一个指向某物的 const 指针,并且您知道某物未声明为const
时,才应使用。
通过const_cast
修改常量是未定义的行为。
编译器看到您正在尝试打印一个常量变量,知道它永远不会更改,因此编译:
cout << "i: " << i << endl;
自:
cout << "i: " << 123 << endl;
请参阅:https://godbolt.org/z/bYb0mx。启用优化后,它可以优化您的代码,只需打印 123:https://godbolt.org/z/4Ttlmj。
最终,编译器会做出假设以创建更快/更小的代码,如果您进入未定义行为的领域,其中一些假设可能是不正确的并产生令人惊讶的结果。
- const_cast静态数组以添加恒常性
- 自动模板参数、数据成员和恒常性
- 有没有办法检测自身内部的类恒常性?
- 为什么const_cast删除指针的恒常性,而不删除指向常量的指针的恒常性?
- 对指针和恒常性兼容性的引用
- 自定义容器中的括号运算符中的恒常性
- C++ 重载分辨率和恒常性
- C++17类模板演绎常性
- C++ 函数匹配和恒常性
- 如何忽略函数模板中的恒常性?
- 常量自动和对象恒常性
- 比较运算符 == 中的共享指针恒常性
- 添加额外的恒常性会导致编译器错误
- 删除模板化函数中的恒常性
- 函数和函数指针等效性
- 无法正确理解我的恒常性
- 模板转换运算符优先级和恒常性
- const_iterator和恒常性const_iterator::value_type
- 使用const_cast来添加恒常性 - 坏主意?
- C++ - 为什么常量函数不强制成员指针上的恒常性?