在const函数中返回对self的间接引用

时间:2015-01-20 03:03:17

标签: c++ pointers const

我学会鄙视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指针?

1 个答案:

答案 0 :(得分:2)

您的代码中没有const个变量,因此没有UB。

void func (const a *ii)中,const表示 ii可能指向aconst a,因此我们不应允许通过此指针进行书写,以防它实际指向const a

但在您的代码中,它实际上并不指向const a


您似乎遇到的根本问题与基本结构有关:

struct C
{
    std::string *ptr;
};

在这种情况下,如果我们有一个变量:

const C c = something;

然后问题是,是否允许写:

*(c.ptr) = "Hello";

C ++的规则说“是的,这很好”。这是因为c.ptrconst,但指向的不是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 *。一个更简单的解决方案是在这里实际有两个不同的类(比如aconst_a)。