我非常熟悉 C/C++ 标准函数声明。我最近看到了这样的事情:
int myfunction(char parameter) const
以上只是一个假设的例子,我什至不知道它是否有意义。我指的是参数之后的部分。常数。这是什么?
一个更真实的例子:
wxGridCellCoordsArray GetSelectedCells() const
这可以在这里找到
那么const
该行末尾的文本到底在做什么呢?
const 表示该函数不会更改任何数据成员,this
除非它们被标记为可变。
只能将成员函数标记为 const,因此这意味着函数内部不会更改任何成员。
The const keyword, when shown after a function, guarantees the function caller that no member data variables will be altered. It also changes the function signature, which is something less known to some C++ programmers. You can actually overload a function in C++ by adding the const keyword after a function with the same name. For example:
void changeValue() const;
void changeValue();
Both of the above functions are valid and an overload of each other. I often see some C++ API's and frameworks use this overload to avoid a plethora of compile errors when users call these functions within const and non-const functions. Whether this is good C++ software engineering is up for debate. I would imagine it is bad practice, but it is good to be aware that it changes the function signature.
For instance given this class,
// In header
class Node {
public:
Node();
void changeValue() const;
~Node();
private:
int value;
};
// in .cpp
void Node::changeValue() const {
this->value = 3; // This will error out because it is modifying member variables
}
There is an exception to this rule. If you declare that a member data variable is mutable, then it can be altered regardless if the function is declared to be const. Using mutable is for the rare situation where an object is declared constant, but in practice has member data variables which need the option to change. One potential example of its use is caching a value that you may not want to repeat the original calculation. This is typically rare... But it is good to be aware of it. A good reference of software engineering decisions around Mutable is the concept of bitwise const vs conceptual const. With bitwise const, the programmer is informing the reader that when const is present, no bits for that const object shall change without a const_cast. With conceptual const, the idea is that the user of the class should not care whether the bits of the mutable variable should change as it does not impact the usage of the class from the user's perception. Here is a good article explaining the difference and the ups and downs of using Mutable - https://www.cprogramming.com/tutorial/const_correctness.html
For instance given this class,
// In header
class Node {
public:
Node();
void changeValue() const;
~Node();
private:
mutable int value;
};
// in .cpp
void Node::changeValue() const {
this->value = 3; // This will not error out because value is mutable
}
这是一种“防御性编程”技术,可帮助防止您自己的编程错误。对于const
函数参数,您声明该函数不应修改该参数,并添加const
编译器以防止您无意中这样做的原因。同样,如果您编写了一个不应更改类的任何成员变量的成员函数,那么您可以像这样声明整个函数const
,它会阻止您这样做。
它还有助于使您的代码自我记录。添加const
到参数会告诉用户“此函数不会修改此参数”。添加const
到成员函数会告诉用户“此函数不会修改类的任何成员”(明确可变的成员除外)。
限制对某些东西的访问,除了那些你真正需要它的场合,通常应该被认为是一件好事。这与您不经常以 root 身份登录到自己的系统的原因完全相同,即使您可以这样做,并且如果您这样做了,您将拥有更多的权力。
方法后面的const
关键字表示隐式this
参数(设置为用于调用该方法的对象的地址)指向一个常量对象。
在 C++ 中。成员函数可能如下所示:
class Foo {
int x;
mutable int y;
public:
void bar () {
Foo *me = this; // * this is an implicit parameter
// that points to the instance used
// to call bar()
assert(&x == &this->x); // * accesses to class members are
// implicitly taken from this
x = 1; // * can modify data members
}
void bar () const {
// Foo *me = this; // * error, since "bar() const" means
// this is a "const Foo *"
const Foo *me = this; // * ok
// x = 1; // * error, cannot modify non-mutable
// members of a "const Foo"
y = 0; // * ok, since y is mutable
}
};
C 中的类比将是分别访问 astruct Foo *
和 a 的函数const struct Foo *
:
struct Foo {
int x;
int y;
};
void Foo_bar (Foo *this) { /* ... */ } /* can modify this->x and this->y */
void cFoo_bar (const Foo *this) { /* ... */ } /* cannot modify this->x nor this->y */
C中没有mutable
类比。