是否在 const 方法未定义行为中修改非常量对象的非可变成员?
Is modifying non-mutable member of non-const object in const method Undefined Behaviour?
dcl.type.cv 提供了一个有趣的例子:
For another example,
struct X {
mutable int i;
int j;
};
struct Y {
X x;
Y();
};
const Y y;
y.x.i++; // well-formed: mutable member can be modified
y.x.j++; // ill-formed: const-qualified member modified
Y* p = const_cast<Y*>(&y); // cast away const-ness of y
p->x.i = 99; // well-formed: mutable member can be modified
p->x.j = 99; // undefined: modifies a const member
这表明,通过 const_cast
,可以修改 const
合格对象的 mutable
成员,而不能使用非 mutable
会员。
据我了解,这是因为 y
本身的原始 const
ness。如果我们去掉 mutable
关键字,const
限定符 y
,但修改 const
方法中的字段,会发生什么情况?
示例如下:
#include <vector>
struct foo {
std::vector<int> vec{};
void bar() const {
auto& raw_ref = const_cast<std::vector<int>&>(vec);
raw_ref.push_back(0); // ok?
auto* raw_this = const_cast<foo*>(this);
raw_this->vec.push_back(0); // ok?
}
};
int main() {
foo f{};
f.bar();
}
它是否表现出未定义的行为?我认为它不会,因为我们正在修改最初非 const
,而是在 const
上下文中。
此外,请注意我提供了两种修改 vec
的方法。一个具有非 const
引用,一个具有指向 this
的非 const
指针(由于 foo::bar
是 const
方法)。考虑到问题的背景,它们在任何特定方面有什么不同吗?我假设两者都可以。
免责声明:我知道 mutable
关键字,但这个设计(不仅有缺陷)只是一个例子。可以假设代码的作者想要禁止每一种修改 vec
的方式,除了 push_back
s.
您引用的段落实际上准确地说明了未定义的内容[dcl.type.cv]
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
非 const 对象的 const reference/pointer 不会使该对象成为 const 对象,您的所有访问都是合式的。
dcl.type.cv 提供了一个有趣的例子:
For another example,
struct X { mutable int i; int j; }; struct Y { X x; Y(); }; const Y y; y.x.i++; // well-formed: mutable member can be modified y.x.j++; // ill-formed: const-qualified member modified Y* p = const_cast<Y*>(&y); // cast away const-ness of y p->x.i = 99; // well-formed: mutable member can be modified p->x.j = 99; // undefined: modifies a const member
这表明,通过 const_cast
,可以修改 const
合格对象的 mutable
成员,而不能使用非 mutable
会员。
据我了解,这是因为 y
本身的原始 const
ness。如果我们去掉 mutable
关键字,const
限定符 y
,但修改 const
方法中的字段,会发生什么情况?
示例如下:
#include <vector>
struct foo {
std::vector<int> vec{};
void bar() const {
auto& raw_ref = const_cast<std::vector<int>&>(vec);
raw_ref.push_back(0); // ok?
auto* raw_this = const_cast<foo*>(this);
raw_this->vec.push_back(0); // ok?
}
};
int main() {
foo f{};
f.bar();
}
它是否表现出未定义的行为?我认为它不会,因为我们正在修改最初非 const
,而是在 const
上下文中。
此外,请注意我提供了两种修改 vec
的方法。一个具有非 const
引用,一个具有指向 this
的非 const
指针(由于 foo::bar
是 const
方法)。考虑到问题的背景,它们在任何特定方面有什么不同吗?我假设两者都可以。
免责声明:我知道 mutable
关键字,但这个设计(不仅有缺陷)只是一个例子。可以假设代码的作者想要禁止每一种修改 vec
的方式,除了 push_back
s.
您引用的段落实际上准确地说明了未定义的内容[dcl.type.cv]
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior.
非 const 对象的 const reference/pointer 不会使该对象成为 const 对象,您的所有访问都是合式的。