英文:
Why am I being told "this method could be const"?
问题
在一个类中,可以写如下代码:
class Foo
{
public:
void DoSomething(int x) const;
private:
int m_bar;
};
但不允许写如下代码:
void Foo::DoSomething(int x) const
{
m_bar = x; // 错误
}
我必须移除 const
修饰符。然而,如果我有以下代码:
struct Data
{
int bar;
};
class Foo
{
public:
void DoSomething(int x) const;
private:
Data * m_data;
};
void Foo::DoSomething(int x) const
{
m_data->bar = x;
}
那么这是允许的,而且如果我移除修饰符,代码验证工具会警告我 "方法可以是 const" 吗?
无论如何,我都不应该能够在 const 方法中修改对象的状态,不管这个状态是如何表示的!
英文:
In a class
class Foo
{
public:
void DoSomething(int x) const;
private:
int m_bar;
};
one is not allowed to write
void Foo::DoSomething(int x) const
{
m_bar = x; // Error
}
I have to remove the const
modifier, However, if I have
struct Data
{
bar;
};
class Foo
{
public:
void DoSomething(int x) const;
private:
Data * m_data;
};
void Foo::DoSomething(int x) const
{
m_data->bar = x;
}
then that's not only fine,but I get warned "method can be const" by code validation tools if I remove the modifier?
I shouldn't be able to modify the state of an object in a const method, irrespective of how that state is represented!
答案1
得分: 7
The const
qualifier告诉编译器该函数不会修改对象的任何成员变量。因此,如果您有一个指针成员变量,const
函数将无法更改指针本身。
但是 这仅适用于实际成员变量。指针实际指向的数据不是常量。为此,您需要一个指向常量对象的指针(例如 Data const* m_data;
)。
英文:
The const
qualifier tells the compiler that the function will not modify any member variables of the object. So if you have a pointer member variable, a const
function will not be able to change the pointer itself.
But that only goes for the actual member variable. The data that the pointer is actually pointing to is not constant. For that you need a pointer to a constant object (e.g. Data const* m_data;
).
答案2
得分: 2
指针指向某个地方。如果你修改一个指针,你就修改了它指向的位置。
因为指针指向某个地方,所以你可以对它们进行解引用来访问指向的对象。修改对象不会修改指针。
为了说明问题,想象一下,你没有指针,而是有一个数组的索引:
struct Data
{
int x;
};
Data my_memory[42];
class Foo
{
public:
void DoSomething(int x) const;
private:
size_t m_index; // "指向"my_memory中的一个Data元素
};
void Foo::DoSomething(int x) const
{
my_memory[m_index].x = x;
}
当然,指针不是数组的索引。尽管作为思维形象,它比你想象的更准确。索引指的是存储在其他地方的实际对象。你可以修改索引,但不会影响对象。你可以使用索引访问对象并修改它,而不会修改索引。这与你的指针所做的事情是一样的。
希望现在很明显 Foo::DoSomething
应该是 const
。你正在修改 Data
对象,而它不是 Foo
的一部分。Foo
只包含一个指向对象的指针。DoSomething
不会修改那个指针。
英文:
Pointers point somewhere. If you modify a pointer you modify where it points to.
Because pointers point somewhere you can dereference them to access the pointee. Modifying the pointee does not modify the pointer.
For the sake of illustration, imagine you had no pointer but instead an index into an array:
struct Data
{
int x;
};
Data my_memory[42];
class Foo
{
public:
void DoSomething(int x) const;
private:
size_t m_index; // "points to" a Data element in my_memory
};
void Foo::DoSomething(int x) const
{
my_memory[m_index].x = x;
}
Of course pointers are not indices into arrays. Though as mental image it is more accurate than you might expect. The index refers to the actual object which is stored elsewhere. You can modify the index which has no effect on the object. You can use the index to access the object and modify it without modifying the index. Thats just the same as your pointer does.
I hope now it is obvious that Foo::DoSomething
should be const
. You are modifiying the Data
object, which is not part of Foo
. Foo
only contains a pointer to the object. DoSomething
does not modify that pointer.
答案3
得分: 0
对象正在某个地址P处占用一些X内存。
带有const
限定符的成员函数无法直接更改此地址上的X内存,这就是函数可以标记为const
的原因。
在下面的情况下,我们可以在const
对象内更改对象的内存:
struct A {
public:
A(): x(5) { x_p =&x;};
void update_x() const { *x_p = 3;}
int x;
int *x_p;
};
编译并运行:
int main()
{
A a;
std::cout << a.x << std::endl;
a.update_x();
std::cout << a.x << std::endl;
}
将得到:
3
5
英文:
The object is taking some X memory at some address P.
A member function of with the const
qualifier, can't change DIRECTLY the memory X at at this address, this is why a function can be mark as const
In the case below, we CAN change the memory of the object inside a const
object
struct A {
public:
A(): x(5) { x_p =&x;};
void update_x() const { *x_p = 3;}
int x;
int *x_p;
};
Compile and run :
int main()
{
A a;
std::cout << a.x << std::endl;
a.update_x();
std::cout << a.x << std::endl;
}
would get:
3
5
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论