我学会鄙视const
。
struct b;
struct a {
b* p;
void nonConst() { p = nullptr;}
b* getP() const { return p;}
};
struct b {
a *p;
a *getP() const { return p;}
};
void func (const a *ii) {
b *uRef = ii->getP();
//dear god, we've just obtained a pointer to a non-const a, starting with const a
a *iii = uRef->getP();
//and we've just modified ii, a const object
iii->nonConst();
}
int main() {
a *i = new a;
b *u = new b;
i->p = u;
u->p = i;
func(i);
}
这会导致任何未定义的行为吗?如果没有,是否违反任何const
规则?如果不是这样,为什么this
被视为指向const
数据的const
指针,而不仅仅是指向非const
数据的const
指针?
答案 0 :(得分:2)
您的代码中没有const
个变量,因此没有UB。
在void func (const a *ii)
中,const
表示 ii
可能指向a
或const a
,因此我们不应允许通过此指针进行书写,以防它实际指向const a
。
但在您的代码中,它实际上并不指向const a
。
您似乎遇到的根本问题与基本结构有关:
struct C
{
std::string *ptr;
};
在这种情况下,如果我们有一个变量:
const C c = something;
然后问题是,是否允许写:
*(c.ptr) = "Hello";
C ++的规则说“是的,这很好”。这是因为c.ptr
是const
,但指向的不是const
。
这是否真的是一个好主意的问题是你必须决定作为你的类接口的一部分(你将在你的课程文档中描述)。
如果字符串的值应该是C
实例的不变量,那么您可能想要禁止它,或者至少阻止它。
返回原始代码,如果您希望const a
代表持有const b
,则需要输入:
b const * getP() const { return p;}
^^^^^
然后调用者将无法编写b *uRef = ii->getP();
,他们必须至少投入const_cast
。
最后,const a
没有一种简单的方法可以实际拥有b const *
,但非{const} a
来保持b *
。一个更简单的解决方案是在这里实际有两个不同的类(比如a
和const_a
)。