提问人:Luchian Grigore 提问时间:4/2/2014 最后编辑:CommunityLuchian Grigore 更新时间:4/6/2014 访问量:691
通过 const 指针修改用 new 创建的对象是否合法?
Is it legal to modify an object created with new through a const pointer?
问:
所以这个答案让我想到了将结果分配给指向 .AFAIK,在这种情况下,您没有理由不能合法地消除恒常性并实际修改对象:new
const
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 扩展还是标准行为?我在实践中从未见过这种情况。如果它是标准的,我会尽可能开始使用它。
答:
const
是类型的一部分。无论您为对象分配动态、静态还是自动存储持续时间都无关紧要。它仍然是.抛弃这种性并改变对象仍然是一个未定义的操作。const
const
const
ness 是类型系统给我们的抽象,用于围绕不可变对象实现安全性;它这样做在很大程度上是为了帮助我们与只读内存进行交互,但这并不意味着它的语义仅限于这种内存。事实上,C++甚至不知道什么是只读内存,什么不是只读内存。
除了这可以从所有常用规则中派生出来之外,对于动态分配的对象没有例外 [lol],标准明确提到了这一点(尽管在注释中):
[C++03: 5.3.4/1]:
new-expression 尝试创建应用它的 type-id (8.1) 或 new-type-id 的对象。该对象的类型是分配的类型。此类型应为完整的对象类型,但不能是抽象类类型或其数组(1.8、3.9、10.4)。[注意:由于引用不是对象,因此引用不能由 new-expression 创建。] [注意:type-id 可以是 cv 限定类型,在这种情况下,new-expression 创建的对象具有 cv 限定类型。 ] [..]
[C++11: 5.3.4/1]:
new-expression 尝试创建应用它的 type-id (8.1) 或 new-type-id 的对象。该对象的类型是分配的类型。此类型应为完整的对象类型,但不能是抽象类类型或其数组(1.8、3.9、10.4)。它是否支持过度对齐类型由实现定义 (3.11)。[ 注意:由于引用不是对象,因此引用不能由 new-expression 创建。—尾注 ] [ 注意:type-id 可以是 cv 限定类型,在这种情况下,new-expression 创建的对象具有 cv 限定类型。 —尾注] [..]
中还给出了一个用法示例。[C++11: 7.1.6.1/4]
不知道你还期待什么。我不能说我自己曾经这样做过,但我看不出有什么特别的理由不这样做。可能有一些技术社会学家可以告诉你,我们很少动态地分配一些东西,只是为了把它当作不可改变的。
评论
new const ...
const
int x = 0; const int *px = new (&x) const int(0); x = 1; cout << *px;
x = 1;
*px
int
new
显然不会创建一个 const 对象(我希望)。
如果你要求创建一个对象,你会得到一个对象。new
const
const
你没有理由不能合法地消除恒常性并实际修改对象。
const_cast
有。原因是语言规范将其明确地称为未定义的行为。所以,在某种程度上,你可以,但这几乎毫无意义。
我不知道你对此有什么期望,但如果你认为问题出在只读内存中分配与否,那就远非重点了。没关系。编译器可以假设这样的对象不能相应地更改和优化,最终会得到意想不到的结果。
评论
const X* x = new X
new X
delete
delete
我看待这个问题的方式是:
X
和 指向它们的指针是不同的类型const X
- 有一个从 到 的隐式转换,但不是相反
X*
const X*
因此,以下情况是合法的,并且在每种情况下都具有相同的类型和行为
x
const X* x = 新 X; const X* x = 新常量 X;
剩下的唯一问题是,在第二种情况下(可能在只读内存中)是否可以调用不同的分配器。答案是否定的,标准中没有这样的规定。
评论
new obviously doesn't create a const object.
为什么这么说呢?new doesn't create a const object
为什么这么说呢?T
const T *ptr = new T;
new
ptr
new
int obj = 2; const int* ptr = &obj; *const_cast<int*>(ptr) = 3;