constメンバ関数とは
以下のように引数の後にconstが明記されたメンバ関数のことです。
メンバ関数内でメンバ変数を使用するがデータの改変を防ぎたい場合これを明示するために使います。
hito.cpp
#include <iostream>
class Hito {
private:
int age = 10;
public:
void output_age() const { // <- constメンバ関数
std::cout << age << std::endl;
}
void grow_a_year_older() {
age++;
}
}
書くとどうなるか
関数内でのメンバ変数の書き換えができなくなります。
以下のように書くことはできません。
hito.cpp
void output_age() const {
age++; // <- [Err]
age = 1; // <- [Err]
grow_a_year_older(); // <- [Err]
std::cout << age << std::endl;
}
利点
コーダーが誤ってメンバ変数を書き換える可能性を抑えられバグを減らすことができます。
デバックの際にconstメンバ関数の中身でメンバ変数が書き換えられていないか確認する必要が減ります。
つまり副作用を抑えられます。
注意点
注意点1: 関数内でメンバ変数を使わない場合
関数内でメンバ変数を使わない場合はconstメンバ関数にするよりも静的関数にした方が良いです。
以下は例です
hito.cpp
static output_age(const int age0) {
std::cout << age0 << std::endl;
}
注意点2: const メンバ変数内であってもメソッド変数が書き換えられてしまう場合がある
メンバ変数をmutableで宣言した場合です
hito.cpp
...
private:
mutable int age = 10; // mutableメンバ変数
...
この場合constメンバ関数内で変数を直接変更することが可能になります。しかしメンバ変数を内部で変更するような関数の呼び出しはエラーになります。
hito.cpp
void output_age() const {
age++; // <- Errにならない
age = 1; // <- Errにならない
grow_a_year_older(); // <- [Err]
std::cout << age << std::endl;
}