c++ - 是否在 const 方法未定义行为中修改非 const 对象的非可变成员?
问题描述
dcl.type.cv提供了一个有趣的例子:
再举一个例子,
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
,可以修改合格对象mutable
的成员const
,而您不能对非mutable
成员执行此操作。
据我了解,这是因为它本身的原始const
性y
。如果我们去掉mutable
关键字const
限定符 fot 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
引用的,一个是非const
指针的(由于是一种方法this
,最初在这个上下文中)。考虑到问题的上下文,它们是否有任何特定的不同?我会假设两者都可以。const
foo::bar
const
免责声明:我知道mutable
关键字,但这种设计(不仅是有缺陷的)只是一个例子。可以假设代码的作者想要禁止vec
除push_back
s 之外的每一种修改方式。
解决方案
您引用的段落实际上准确地说明了未定义的内容[dcl.type.cv]
除了可以修改任何声明为 mutable 的类成员外,任何在 const 对象的生命周期内修改其的尝试都会导致未定义的行为。
指向非 const 对象的 const 引用/指针不会使该对象成为 const 对象,您的所有访问都是格式正确的。
推荐阅读
- c# - EF Core 3.1 迁移工具因依赖 .NET Core 2.0 而失败
- c# - 如何通过按住左键单击启用布尔值并禁用该布尔值
- python-3.x - 埃拉托色尼筛法的实现和比较
- c# - Zenject 将普通类注入 Monobehaviour
- docker - 没有 Internet 连接的 AirGap Widows 2019 服务器上的 Docker Hub
- python - 如何解决此错误 logits 和标签必须具有相同的第一维
- java - 调用 Android Java JNI GetDoubleField() 时发出 SIGABORT
- microsoft-graph-api - 图资源管理器中加入团队 api 的“ResourceNotFound”和 404
- visual-studio - MSBuild 目标未在 NET Core 项目中运行
- mysql - 在nodejs中保存数组中的数据库条目