在 const 函数中返回对 self 的间接引用
Returning indirect reference to self in const function
我正在学会鄙视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
指针?
你的代码中没有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++ 的规则说 "Yes, this is fine"。这是因为 c.ptr
是 const
,但指向的东西不是 const
。
这是否是一个好主意的问题是您必须在 class 界面中决定的(您将在 class 的文档中描述) ).
如果字符串的值应该是 C
实例的不变量,那么您可能希望禁止这样做,或者至少不鼓励这样做。
回到你原来的代码,如果你想要一个 const a
代表持有一个 const b
,那么你需要输入:
b const * getP() const { return p;}
^^^^^
然后调用者将无法写入 b *uRef = ii->getP();
,他们至少必须输入 const_cast
.
最后,没有简单的方法让 const a
实际持有 b const *
,但非 const a
持有 b *
。一个更简单的解决方案是实际上有两个不同的 classes(比如 a
和 const_a
)。
我正在学会鄙视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
指针?
你的代码中没有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++ 的规则说 "Yes, this is fine"。这是因为 c.ptr
是 const
,但指向的东西不是 const
。
这是否是一个好主意的问题是您必须在 class 界面中决定的(您将在 class 的文档中描述) ).
如果字符串的值应该是 C
实例的不变量,那么您可能希望禁止这样做,或者至少不鼓励这样做。
回到你原来的代码,如果你想要一个 const a
代表持有一个 const b
,那么你需要输入:
b const * getP() const { return p;}
^^^^^
然后调用者将无法写入 b *uRef = ii->getP();
,他们至少必须输入 const_cast
.
最后,没有简单的方法让 const a
实际持有 b const *
,但非 const a
持有 b *
。一个更简单的解决方案是实际上有两个不同的 classes(比如 a
和 const_a
)。