为什么在C ++中允许从外部修改常量对象的指针成员变量的内存?

时间:2015-08-05 12:56:18

标签: c++ pointers const transitivity

我一直试图理解当我在C ++中使用常量参数和指针变量编写一个函数时,const标志不会保护底层内存不受修改。 例如,在名为operator=()的类的X函数中执行以下操作是完全合法的:

class X
{
public:
    X& operator=(const X& other)
    {
        this->data = other.data; //(*)
        return *this;
    }

private:
    int* data;
};

(*):这与以下内容相同:

int* some_pointer;
int* const other_pointer = some_pointer;
int* class_pointer = other_pointer;

但不一样:

const int* other_pointer; 
int* class_pointer = other_pointer;

会产生以下错误:

error: invalid conversion from 'const int*' to 'int*' [-fpermissive]
 int* class_pointer = other_pointer;
                      ^

我理解为什么other.x被投放到int* const,但我不明白为什么它不会同时投放到const* int(这是{ {1}})。当我用const int* const参数编写函数时,我的逻辑表明该参数内的任何内容都应该继承constness,因为这应该是const的目的,以保护底层数据不被修改。

当从类const版本之外访问指针成员时,我认为应该合理地期望对象的const关键字应该保护得到的任何东西(甚至是内存)从修改中走出课堂。反对这一点的论点是,外部记忆不属于对象,所以它也不应该是保护它的责任。我对它的看法是,在这种情况下(在任何其他情况下,当它被访问到其他任何类型的访问权限时),我们从const对象中取出一些东西。换句话说,它提供了对自身之外的东西的可见性。那么,不能提高可见度const背后的原因是什么?这不会改变代码的任何其他位置的内存的可访问性权限!

4 个答案:

答案 0 :(得分:5)

  

“当我用const参数编写函数时,我的逻辑表明该参数内的任何内容都应该继承const,因为这应该是const的目的,以保护底层数据不被修改。”

你是对的,但是存储在X - 对象内的指针将指向对象。外部不受X常量的影响,仅受X内存储的数据的影响。

答案 1 :(得分:1)

为什么你认为,因为指针是常量,指向的应该是常量?它不一定遵循。

有时您需要一个必须始终指向特定位置的指针,但您可以通过该指针修改指示的位置。 class X没有任何内容表明您不应该将内存data更改为。{1}}。

更重要的是,您对const关键字的思考错误。给定

X& operator=(const X& other)

您所做的就是告诉编译器您不打算在other内更改operator=()并要求编译器阻止您忘记这样做。没有更多,没有更少。它对other之外的operator=()的常量以及other内指针内的任何指针的常量都没有任何说明。

答案 2 :(得分:0)

int* const other_pointer
declare other_pointer as const pointer to int

而不是:

const int* other_pointer
declare other_pointer as pointer to const int

http://cdecl.org/提供

注意const的位置差异。

答案 3 :(得分:0)

您没有更改other.data的值,因此没有const违规。您当然可以修改other.data指向的对象,但这超出了编译器强制执行const正确性的责任。