constプログラムのセマンティクスに関するものであり、実装の詳細に関するものではありません。constオブジェクトの可視状態を変更しない場合はメンバー関数をマークする必要があり、それ自体であるオブジェクトで呼び出し可能にする必要がありますconst。constclassのメンバ関数内ではX、 の型thisはX const *: 定数Xオブジェクトへのポインタです。したがって、すべてのメンバー変数は実質的constにそのメンバー関数内にあります (1 つを除くmutable)。オブジェクトがある場合、そのオブジェクトに対してのみメンバー関数をconst呼び出すことができます。const
mutableメンバー関数内でもメンバー変数が変更される可能性があることを示すために使用できますconst。これは通常、結果のキャッシュに使用される変数を識別するために使用されるか、ミューテックス (constメンバー関数でミューテックスをロックする必要があります) やカウンターを使用するなど、実際の監視可能な状態に影響を与えない変数に対して使用されます。
class X
{
int data;
mutable boost::mutex m;
public:
void set_data(int i)
{
boost::lock_guard<boost::mutex> lk(m);
data=i;
}
int get_data() const // we want to be able to get the data on a const object
{
boost::lock_guard<boost::mutex> lk(m); // this requires m to be non-const
return data;
}
};
直接ではなくポインターによってデータを保持する場合 (std::auto_ptrまたはなどのスマート ポインターを含むboost::shared_ptr)、ポインターはconstメンバーconst関数になりますが、ポイント先のデータにはならないため、ポイント先のデータを変更できます。
キャッシングに関しては、通常、呼び出し間で状態が変化する可能性があるため、コンパイラーはこれを行うことができません (特に、ミューテックスを使用したマルチスレッドの例では)。ただし、定義がインラインの場合、コンパイラはコードを呼び出し元の関数に取り込み、そこに表示される内容を最適化できます。これにより、関数が事実上1 回だけ呼び出される可能性があります。
C++ 標準 (C++0x)の次のバージョンには、新しいキーワードconstexpr. タグ付けされた関数constexprは定数値を返すため、結果をキャッシュできます。そのような関数でできることには制限があります (コンパイラがこの事実を検証できるようにするため)。