是否在const方法未定义行为中修改了非const对象的非可变成员?

时间:2019-02-18 11:39:11

标签: c++ const language-lawyer const-cast

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的{​​{1}}限定词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的指向const的指针(由于this是{{ 1}}方法)。根据问题的上下文,它们在任何特定方面是否有所不同?我认为这两个都还可以。

免责声明:我知道const关键字,但是这种设计(不仅存在缺陷)只是一个示例。可以假设代码的作者想禁止除foo::bar之外的所有修改const的单一方法。

1 个答案:

答案 0 :(得分:3)

您引用的段落实际上清楚地说明了未定义的[dcl.type.cv]

  

除了声明为可变的任何类成员都可以修改之外,任何在其生存期内修改const对象的尝试都将导致未定义的行为。

指向非const对象的const引用/指针不会使该对象成为const对象,您的所有访问都格式正确。