通过常量指针修改使用 new 创建的对象是否合法
Is it legal to modify an object created with new through a const pointer?
所以这个答案让我想到了将new
的结果分配给指向const
的指针的场景。AFAIK,在这种情况下,您没有理由不能合法地const_cast
恒常性并实际修改对象:
struct X{int x;};
//....
const X* x = new X;
const_cast<X*>(x)->x = 0; // okay
但后来我想 - 如果你真的想new
创建一个const
对象怎么办。所以我尝试了
struct X{};
//....
const X* x = new const X;
它编译了!!
这是 GCC 扩展还是标准行为?我在实践中从未见过这种情况。如果它是标准的,我会尽可能开始使用它。
new
显然不会创建一个 const 对象(我希望)。
如果要求new
创建const
对象,则会得到一个const
对象。
您没有理由不能合法地
const_cast
恒常性并实际修改对象。
有。原因是语言规范明确地将其称为未定义的行为。所以,在某种程度上,你可以,但这几乎没有任何意义。
我不知道你对此有什么期望,但如果你认为问题是在只读内存中分配与否,那就远非重点了。没关系。编译器可以假设这样的对象无法相应地更改和优化,并且最终会得到意想不到的结果。
const
是该类型的一部分。无论您是否分配具有动态、静态或自动存储持续时间的对象,都无关紧要。它仍然const
.抛弃这种const
性并改变对象仍然是一个未定义的操作。
const
ness是类型系统赋予我们围绕不可变对象实现安全性的抽象;它这样做在很大程度上是为了帮助我们与只读内存进行交互,但这并不意味着它的语义仅限于这种内存。事实上,C++甚至不知道什么是只读内存,什么不是只读内存。
除了可以从所有常用规则派生出来之外,对于动态分配的对象没有例外[lol],标准明确提到了这一点(尽管在注释中):
[C++03: 5.3.4/1]:
new-expression 尝试创建应用该表达式的类型 id (8.1) 或新类型 ID 的对象。该对象的类型是分配的类型。此类型应是完整的对象类型,但不是抽象类类型或其数组(1.8,3.9,10.4)。[注意:由于引用不是对象,因此不能由新表达式创建引用。] [注意:类型ID可以是cv限定的类型,在这种情况下,new-expression创建的对象具有cv限定的类型。
[C++11: 5.3.4/1]:
new-expression 尝试创建应用它的类型 id (8.1) 或新类型 id 的对象。该对象的类型是分配的类型。此类型应是完整的对象类型,但不是抽象类类型或其数组(1.8,3.9,10.4)。是否支持过度对齐的类型由实现定义 (3.11)。[ 注意:由于引用不是对象,因此不能由新表达式创建引用。—尾注 ] [ 注意:类型ID可以是CV限定的类型,在这种情况下,新表达式创建的对象具有CV限定类型。
[C++11: 7.1.6.1/4]
中还给出了一个使用示例。
不知道你还期待什么。我不能说我自己曾经这样做过,但我看不出有什么特别的理由不这样做。可能有一些技术社会学家可以告诉你统计数据,我们很少动态分配某些东西,只是将其视为不可变的。
我看待这个问题的方式是:
-
X
和const X
以及指向它们的指针是不同的类型 - 有一个从
X*
到const X*
的隐式转换,但不是相反 -
因此,以下内容是合法的,每种情况下
x
具有相同的类型和行为常量 X* x = 新 X;常量 X* x = 新的常量 X;
剩下的唯一问题是,在第二种情况下(可能在只读内存中)是否可以调用不同的分配器。答案是否定的,标准中没有这样的规定。
- 使用基类指针创建对象时,缺少派生类析构函数
- 如何创建对象函数指针C++映射?
- C++创建对象数组
- 在 C++ 的 Switch Case 中创建对象后对对象调用方法
- 如何获取在 main() 函数中构造的类的创建对象?
- 基于文件中的条目创建对象
- 错误:创建对象后无法分配区域
- C++ 通过输入创建对象
- 堆还是堆栈用于创建对象?
- 使用 C++ 创建对象数组
- 使用unique_ptr创建对象
- C++递归地在类构造函数中创建对象
- 通过向构造函数其他对象引用页面来创建对象
- ReactiveX (rx) - 在对象上应用可观察对象,而不是在可观察对象中创建对象
- 如何在OSX上正确创建C++对象文件(.o)
- 编译器是否会创建vtable,而不考虑在c++中创建对象
- 创建对象并防止被破坏
- 在C++中,友元类可以从友元类创建对象吗
- 只在堆中创建C++对象
- 创建用户定义的复制构造函数时无法创建对象