为什么我可以用c++ 11中的const函数来修改类?

时间:2021-09-19 07:14:45

I'm a bit newbie to CPP and I don't know why the setValue() const works meanwhile it's a const.

我对CPP有点陌生,我不知道为什么setValue() const可以工作,同时它也是const。

Why the class allows modification from a const public

为什么类允许来自const公共的修改

It seems really odd, there is no error on g++ -Wall or with MS Visual C++

看起来很奇怪,g+ -Wall和MS Visual c++都没有错误

Here is my code:

这是我的代码:

main.cpp

main.cpp

#include <iostream>
#include <cassert>
#include "DArray.h"

int main(void)
{
    DArray darray(1);
    darray.setValue(0, 42);
    assert(darray.getValue(0) == 42);
    darray.~DArray();
    system("pause");
    return 0;
}

DArray.h

DArray.h

class DArray
{
private:
    int* tab;

public:
    DArray();
    DArray(unsigned int n);
    ~DArray();

    int& getValue(unsigned int n) const;
    void setValue(unsigned int n, int value) const;
};

DArray.cpp

DArray.cpp

#include "DArray.h"

DArray::DArray()
{

}

DArray::DArray(unsigned int n)
{
    tab = new int[n];
}

DArray::~DArray()
{
    delete[] tab;
    tab = nullptr;
}

int& DArray::getValue(unsigned n) const
{
    return tab[n];
}

void DArray::setValue(unsigned n, int value) const // HERE
{
    tab[n] = value;
}

3 个解决方案

#1


17  

It is because you do not modify it. When you do:

这是因为您不修改它。当你做的事:

int* tab

tab contains only an address. Then in

选项卡只包含一个地址。然后在

void DArray::setValue(unsigned n, int value) const // HERE
{
    tab[n] = value;
}

You do not modify this address, you modify some memory after it. Thus you do not modify your class.

你不修改这个地址,你在它之后修改一些内存。因此不修改类。

If instead, you used

如果相反,你使用

std::vector<int> tab

You would have an error in setValue because you would modify an element of your class.

您将在setValue中出现错误,因为您将修改类的一个元素。

#2


6  

First of all, don't call explicitely the destructor of your class, this will be called when the variable goes out of scope automatically.

首先,不要显式地调用类的析构函数,这将在变量自动超出范围时被调用。

darray.~DArray();

darray。~ darray();

What you are promising with const in the method is that the member variables will not be modified. The variable int* tab is a pointer to an int. With your setValue function you are not changing the address of the pointer (which is promised not to be changed by the final const in the signature of your method) but the int value pointed by it. This is fine.

在const方法中,您承诺的是成员变量不会被修改。变量int*选项卡是指向int的指针。使用setValue函数时,你不会改变指针的地址(保证不会被你的方法签名中的最后一个const所改变),而是改变指针所指向的int值。这是很好。

However, if you change the pointer address, for example with tab = nullptr, you will see a compiler error like:

但是,如果您更改指针地址,例如使用tab = nullptr,您将看到编译器错误如下:

error: assignment of member 'DArray::tab' in read-only object

错误:在只读对象中分配成员'DArray:::tab'

#3


2  

Why can I modify the class with a const function in C++11?

为什么我可以用c++ 11中的const函数来修改类?

It is possible to modify mutable state of the object. It is technically also possible to modify the non-mutable state using const_cast, but it would be a bad idea to do so because if the object itself is const, then behaviour would be undefined.

可以修改对象的可变状态。使用const_cast修改非可变状态在技术上也是可能的,但是这样做不是一个好主意,因为如果对象本身是const,那么行为将是未定义的。

That's however not what you do in this code.

然而,这并不是您在代码中所做的。

why the setValue() const works meanwhile it's a const.

为什么setValue() const同时工作,它是一个常量。

Because it doesn't modify any member of this. It modifies an array that is pointed by a pointer to non-const. Constness of a member function, or constness of the object is not transfer to an indirectly pointed object.

因为它不修改任何元素。它修改由指向非const的指针指向的数组。一个成员函数的一致性,或对象的一致性不会转移到一个间接指向的对象。

#1


17  

It is because you do not modify it. When you do:

这是因为您不修改它。当你做的事:

int* tab

tab contains only an address. Then in

选项卡只包含一个地址。然后在

void DArray::setValue(unsigned n, int value) const // HERE
{
    tab[n] = value;
}

You do not modify this address, you modify some memory after it. Thus you do not modify your class.

你不修改这个地址,你在它之后修改一些内存。因此不修改类。

If instead, you used

如果相反,你使用

std::vector<int> tab

You would have an error in setValue because you would modify an element of your class.

您将在setValue中出现错误,因为您将修改类的一个元素。

#2


6  

First of all, don't call explicitely the destructor of your class, this will be called when the variable goes out of scope automatically.

首先,不要显式地调用类的析构函数,这将在变量自动超出范围时被调用。

darray.~DArray();

darray。~ darray();

What you are promising with const in the method is that the member variables will not be modified. The variable int* tab is a pointer to an int. With your setValue function you are not changing the address of the pointer (which is promised not to be changed by the final const in the signature of your method) but the int value pointed by it. This is fine.

在const方法中,您承诺的是成员变量不会被修改。变量int*选项卡是指向int的指针。使用setValue函数时,你不会改变指针的地址(保证不会被你的方法签名中的最后一个const所改变),而是改变指针所指向的int值。这是很好。

However, if you change the pointer address, for example with tab = nullptr, you will see a compiler error like:

但是,如果您更改指针地址,例如使用tab = nullptr,您将看到编译器错误如下:

error: assignment of member 'DArray::tab' in read-only object

错误:在只读对象中分配成员'DArray:::tab'

#3


2  

Why can I modify the class with a const function in C++11?

为什么我可以用c++ 11中的const函数来修改类?

It is possible to modify mutable state of the object. It is technically also possible to modify the non-mutable state using const_cast, but it would be a bad idea to do so because if the object itself is const, then behaviour would be undefined.

可以修改对象的可变状态。使用const_cast修改非可变状态在技术上也是可能的,但是这样做不是一个好主意,因为如果对象本身是const,那么行为将是未定义的。

That's however not what you do in this code.

然而,这并不是您在代码中所做的。

why the setValue() const works meanwhile it's a const.

为什么setValue() const同时工作,它是一个常量。

Because it doesn't modify any member of this. It modifies an array that is pointed by a pointer to non-const. Constness of a member function, or constness of the object is not transfer to an indirectly pointed object.

因为它不修改任何元素。它修改由指向非const的指针指向的数组。一个成员函数的一致性,或对象的一致性不会转移到一个间接指向的对象。