微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

指向const对象的指针可以改变对象吗?

如何解决指向const对象的指针可以改变对象吗?

指向 const 对象的指针不允许更改对象。例如:

class foo {
    public:
        int m_data;
        
        foo() : m_data{11} {}
};

void change(const foo *obj)
{
    obj -> m_data = 21;   // gives error,normal
}

这是正常且正常的行为。

我不明白的是,当我们添加一个额外的指针变量时,无论是相同类型(如foo *)还是其他类型(如bar *),但不是基本的像 int * 这样的类型,那么我们可以改变指针指向的值(从一个指向 const 类型本身的指针)。

这怎么可能?

class foo {
    public:
        int m_data;
        foo *m_next;
        
        foo() : m_data{11},m_next{nullptr} {}
};

void change(const foo *obj)
{
    obj -> m_next -> m_data = 21;   // does not give any error! why?
}

如果我们在 foo 中采用其他类型,例如 bar *,也会发生这种情况。

为什么会这样?我如何定义函数才能确保我的函数不能更改对象指向的值?

解决方法

obj -> m_next -> m_data = 21;   // does not give any error! why?

因为这不会改变对象。此对象的 m_next 指针与之前完全相同。

这只会改变 m_next 指向的任何内容。这与拥有此 m_next 指针的对象无关。

现在,另一方面,如果您尝试将某些内容分配给 m_next 指针本身,而不是它指向的任何内容,那么您将得到您所期望的错误。

对象包含的唯一内容是它的枚举成员。这行代码没有改变它们。

,

在您的示例中,foo* m_next 是指向可变 foo 对象的指针成员变量。指针本身被认为是对象实例的一部分,而不是被指向的对象。

通过更改 m_next,您正在更改指针,该指针被视为 foo 实例的一部分。在 obj->m_next = nullptr; 中执行类似 change 的操作是无效的,因为您正在更改作为常量 foo 实例一部分的内存。 (注意:不要在实际代码中将随机指针设置为 null,除非您确定它是安全的,或者可能存在内存泄漏)。

通过通过 m_next 访问由 m_next-> 指向的对象,您正在访问另一个对象的内存,该对象不属于传递给 change 的 const 实例的一部分。这是完全正确的。

你可以说常量不是传递性的; const 对象不会通过它(通过指针)const 访问对象。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。