const メンバ関数の落とし穴 ― 2012年01月18日 12時14分30秒
const メンバ関数はメンバ変数を変更しないので、もしコンパイラが違反しているのを見つけられれば、警告をだす。例えば、
% cat const.cpp
class A
{
int i;
public:
A():i(1){}
void increment() const{ ++i; }
};
int main()
{
A a;
}
をコンパイルすると、
% CC const.cpp
const.cpp: In member function 'void A::increment() const':
const.cpp:6: error: increment of data-member 'A::i' in read-only structure
と、オブジェクトファイルが生成されない。それにこの様な簡単な関数であれば、一目瞭然だ。
ところが、なかには一目見ただけでは、メンバ変数が変更されているのが判らないような、副作用によって実際にはメンバ関数が変更される様なコードもある。コンパイラもエラーを認識できないような物もだ。何回か遭遇したことはあるが、昔の事なので、具体的な例を上げられないのが残念だが。
さて、その様な場合どのようなコードが生成されるかと言うと、関数内での変更が、関数を出ると無効になっていた場合が多かった。厄介なのが、メンバ変数の値がずれていったり、酷いときはポインタが無効になっていたりする。症状としては、いつの間にか値が合わなくなっていったり、何も無さそうなところでコアダンプしたりするから厄介だ。加えて、コードを追っているときも const に目がいって、この関数内では値は書き換えられないと思い込んでしまうため、問題点を取り逃しやすい。
最近のコメント