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

标签 c++ pointers constants

我正在学习鄙视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 可能指向一个 aconst a,因此我们不应允许通过此指针进行写入,以防它实际指向 const a

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


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

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

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

const C c = something;

那么问题是,是否允许这样写:

*(c.ptr) = "Hello";

C++ 的规则说“是的,这很好”。这是因为c.ptrconst,但是指向的东西不是const

这是否真的是一个好主意的问题是您必须作为类接口(interface)的一部分来决定的(您将在类的文档中对其进行描述)。

如果字符串的值应该是 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)。

关于c++ - 在 const 函数中返回对 self 的间接引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28037094/

相关文章:

c - const 关键字的这种用法是否符合其意图?

c++ - const char *p = "some_string"和 const char[] = "some_string"在内存分配方面的区别

c++ - volatile 但不 protected 读取能否产生无限期的陈旧值? (在真实硬件上)

c - 指针的第一个字符

c - 在 `const` 数组上使用 memset() 函数是否合法?

c - C 中的换行常量

c++ - 在 Windows 中可靠地写入和移动文件

c++ - Lambda 闭包类型构造函数

c - 为什么在 C 中遍历单链表时 NULL 指针检查不起作用?

pointers - Setter 方法不设置结构属性 Golang