为什么 const_cast 删除指针的常量性而不是指向常量的指针?
Why does const_cast remove constness for a pointer but not for a pointer to a const?
我知道 const_cast
使用指针和引用。
我假设 const_cast
的输入应该是指针或引用。我想知道如果输入是 pointer/reference 到 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
参考 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
}
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
的输入是 pointer/reference.
请帮助我理解这背后的哲学。谢谢。
(2)和(3)原理相同,所以只说(2)。
行
const_cast<int&>(ri) = 321;
有未定义的行为。
您不能根据标准修改 const
对象,即使使用 const_cast
也是如此。如果从 pointer/reference 中删除 const
,并修改 pointed/referenced 对象,则 pointed/referenced 对象不得首先声明为 const
。
const_cast
应该只用于,当你出于某种原因有一个指向某物的 const 指针,并且你知道某物没有被声明为 const
.
通过 const_cast
修改常量是未定义的行为。
编译器看到您正在尝试打印一个常量变量,知道它永远不会改变所以编译:
cout << "i: " << i << endl;
至:
cout << "i: " << 123 << endl;
参见:https://godbolt.org/z/bYb0mx. With optimisations enabled it optimises your code to just printing 123: https://godbolt.org/z/4Ttlmj。
编译器最终会做出假设以创建 faster/smaller 代码,如果您进入未定义行为的领域,其中一些假设可能不正确并产生令人惊讶的结果。
常量有两种
对象的常量 是对象固有的属性。它不能改变。
想一想印刷书中的一页。可以看成一串字符,不能改变。它说它说什么,仅此而已。所以这是一个const string
。
现在想想黑板。上面可能写着什么。您可以擦除它并写其他东西。所以黑板是非常量 string
.
另一种常量是指针和引用常量。这种常量性不是指向对象的固有属性,而是权限。它说你不允许通过这个指针修改对象。它没有说明对象本身是否可以修改。
所以如果你有一个const指针,你不一定知道它真正指向什么。也许这是一个书页。也许这是一块黑板。指针不告诉。
现在,如果您不知何故知道它确实是一块黑板,您可能会很讨厌并要求获得许可才能继续并更改上面写的内容。这就是 const_cast 所做的。它允许您做某事。
如果您请求修改字符串的权限,而结果却是打印的页面,会发生什么情况?你得到你的许可,你继续擦除它......然后......究竟发生了什么是undefined。也许什么都没有。也许打印被弄脏了,你既不能识别原始字符串,也不能在上面写任何东西。也许你的世界会爆炸成碎片。你可以试试看,但不能保证明天会发生同样的事情。
我知道 const_cast
使用指针和引用。
我假设 const_cast
的输入应该是指针或引用。我想知道如果输入是 pointer/reference 到 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
参考 const 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 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 }
(1) 按预期工作,但我无法理解为什么 (2) & ( 3) 不像我想的那样工作,尽管 const_cast
的输入是 pointer/reference.
请帮助我理解这背后的哲学。谢谢。
(2)和(3)原理相同,所以只说(2)。
行
const_cast<int&>(ri) = 321;
有未定义的行为。
您不能根据标准修改 const
对象,即使使用 const_cast
也是如此。如果从 pointer/reference 中删除 const
,并修改 pointed/referenced 对象,则 pointed/referenced 对象不得首先声明为 const
。
const_cast
应该只用于,当你出于某种原因有一个指向某物的 const 指针,并且你知道某物没有被声明为 const
.
通过 const_cast
修改常量是未定义的行为。
编译器看到您正在尝试打印一个常量变量,知道它永远不会改变所以编译:
cout << "i: " << i << endl;
至:
cout << "i: " << 123 << endl;
参见:https://godbolt.org/z/bYb0mx. With optimisations enabled it optimises your code to just printing 123: https://godbolt.org/z/4Ttlmj。
编译器最终会做出假设以创建 faster/smaller 代码,如果您进入未定义行为的领域,其中一些假设可能不正确并产生令人惊讶的结果。
常量有两种
对象的常量 是对象固有的属性。它不能改变。
想一想印刷书中的一页。可以看成一串字符,不能改变。它说它说什么,仅此而已。所以这是一个const string
。
现在想想黑板。上面可能写着什么。您可以擦除它并写其他东西。所以黑板是非常量 string
.
另一种常量是指针和引用常量。这种常量性不是指向对象的固有属性,而是权限。它说你不允许通过这个指针修改对象。它没有说明对象本身是否可以修改。
所以如果你有一个const指针,你不一定知道它真正指向什么。也许这是一个书页。也许这是一块黑板。指针不告诉。
现在,如果您不知何故知道它确实是一块黑板,您可能会很讨厌并要求获得许可才能继续并更改上面写的内容。这就是 const_cast 所做的。它允许您做某事。
如果您请求修改字符串的权限,而结果却是打印的页面,会发生什么情况?你得到你的许可,你继续擦除它......然后......究竟发生了什么是undefined。也许什么都没有。也许打印被弄脏了,你既不能识别原始字符串,也不能在上面写任何东西。也许你的世界会爆炸成碎片。你可以试试看,但不能保证明天会发生同样的事情。