下面的代码是不好的做法还是未定义的行为?本质上,我正在调用 const func 来修改未标记为可变的成员。链接到 demo
感谢 Mehrdad 启发了这个问题(他的问题 Does this code subvert the C++ type system? )和 david 对演示的小改进。
#include <iostream>
using namespace std;
struct BreakConst
{
int v;
int *p;
BreakConst() { v = 0; p = &v; }
void break_stuff() const { ++*p; }
};
void f(const BreakConst& bc) {
bc.break_stuff();
}
大多数答案所基于的原始版本:
由 David Rodríguez、jpalecek、Mehrdad 回答
是的:这是“未定义的行为”
int main()
{
const BreakConst bc;
cout << bc.v << endl; // 0
bc.break_stuff(); // O:)
cout << bc.v << endl; // 1
return 0;
}
新的备选问题:
梅赫达德回答
否:这不是“未定义的行为”
int main()
{
BreakConst bc;
cout << bc.v << endl; // 0
f(bc); // O:)
cout << bc.v << endl; // 1
return 0;
}
结果:
0
1
最佳答案
在这种情况下,我会说这是未定义的行为。 bc
是一个 const
对象,所以它的所有子对象(较少的 mutable
)1,因此 bc.v
也应该是并且修改 const
对象,无论如何实现,都是 UB2。
[1] C++03 3.9.3/3:
Each non-static, non-mutable, non-reference data member of a const-qualified class object is const- qualified...
[2] C++03 7.1.5.1/4:
Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.
EDIT 回应问题的编辑:不,代码的修改版本不会导致未定义的行为。这可能是不好的做法,但实际上有时可能很有用。你可以,例如。使用它通过 const-iterators (DRY) 为您的类实现迭代器:
class const_iterator
{
public:
const T& dereference() const; // complicated
};
class iterator : public const_iterator
{
public:
T& dereference() const { return const_cast<T&>(const_iterator::dereference()); }
};
当然,这依赖于 iterator
只能由可变容器构成、const 和非常量版本没有区别(没有 COW 等)等事实,但是相当普遍。
关于c++ - 在 const 成员不良做法或 UB 中修改 const 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11091385/