const修飾子とは
const修飾子
は、オブジェクト変更を行わない(行いたくない)型や変数宣言、メンバ関数につける修飾子です。
本記事では、その中でも特に重要なconstメンバ関数
について紹介します。
constメンバ関数がなぜ重要か
どこでオブジェクトが書き換わるかわからないとバグを埋め込みやすくなってしまいます。
そこでconstメンバ関数
を使って、const操作、非const操作をわけて定義することで、書き換えの影響範囲を小さくする方法を説明します。
main.cpp
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Person
{
public:
void print() const{cout<<name;}
void set(string const& str){name=str;}
private:
string name;
};
//実行できない
void f(Person const& p)
{
p.name="abc";
}
void g(vector<Person> const& v)
{
v.at(0).set("aaa");
}
int main()
{
Person p;
Person const& p2=p;
vector<Person>v;
g(v);//const修飾子がついているため、変数の中身を書き換えることができない
f(p);//fも同様
}
関数の引数にconstをつけると、オブジェクトを変更できなくなります。
main.cpp
#include<iostream>
class Person
{
public:
mutable std::string name;
void print() const{std::cout<<name;}
};
void f(Person const& p)
{
p.name="aaa";
}
int main()
{
Person p;
f(p); // mutableがついていると値の変更が可能
p.print(); //aaaと表示される
return 0;
}
このように書き換える必要のある変数にはmutable修飾子
をつけることで、オブジェクトの書き換えができるようになります。
最後に
constメンバ関数
を正しく定義されていないクラスは、扱いにくいクラスになってしまいます。
開発チーム全員で、constメンバ関数
の重要性を理解し徹底していくべきでしょう。
また、この記事では紹介しませんが、 const_cast
を使うことで強制的に非const型にキャストすることもできます。
もちろんmutable
やconst_cast
は慎重に扱う必要があります。