関数の後に const キーワードを指定すると、関数の呼び出し元はメンバー データ変数が変更されないことが保証されます。また、一部の C++ プログラマにはあまり知られていない関数シグネチャも変更されます。同じ名前の関数の後に const キーワードを追加することで、実際に C++ で関数をオーバーロードできます。例えば:
void changeValue() const;
void changeValue();
上記の関数は両方とも有効であり、相互にオーバーロードされています。一部の C++ API とフレームワークがこのオーバーロードを使用して、ユーザーが const および非 const 関数内でこれらの関数を呼び出すときに、大量のコンパイル エラーを回避するのをよく見かけます。これが優れた C++ ソフトウェア エンジニアリングであるかどうかは、議論の余地があります。悪い習慣だと思いますが、関数のシグネチャが変わることに注意してください。
たとえば、このクラスが与えられた場合、
// In header
class Node {
public:
Node();
void changeValue() const;
~Node();
private:
int value;
};
// .cpp で
void Node::changeValue() const {
this->value = 3; // This will error out because it is modifying member variables
}
この規則には例外があります。メンバー データ変数が変更可能であることを宣言すると、関数が const として宣言されているかどうかに関係なく変更できます。mutable を使用するのは、オブジェクトが定数として宣言されているが、実際には変更するオプションが必要なメンバー データ変数があるというまれな状況です。その使用例として考えられるのは、元の計算を繰り返したくない値をキャッシュすることです。これは通常はまれです... しかし、知っておくとよいでしょう。Mutable に関するソフトウェア エンジニアリングの決定の良いリファレンスは、ビットごとの const と概念的な const の概念です。ビットごとの const を使用すると、プログラマーは、const が存在する場合、その const オブジェクトのビットは const_cast なしでは変更されないことをリーダーに通知します。概念的な const で、クラスのユーザーは、変更可能な変数のビットが変更されるべきかどうかを気にするべきではないという考えです。これは、ユーザーの認識によるクラスの使用に影響を与えないためです。Mutable を使用することの違いと浮き沈みを説明する良い記事があります -https://www.cprogramming.com/tutorial/const_correctness.html
たとえば、このクラスが与えられた場合、
// In header
class Node {
public:
Node();
void changeValue() const;
~Node();
private:
mutable int value;
};
// .cpp で
void Node::changeValue() const {
this->value = 3; // This will not error out because value is mutable
}