Programmingシステム/C++ 開発者

C++におけるキーワード 'mutable', 'volatile', および 'const' の違いについて教えてください。それらは何に使用され、誤った使い方でどのような典型的なエラーが発生しますか?

Hintsage AIアシスタントで面接を突破

回答

const は、コンパイラに対して変数が不変である(初期化後に変更できない)ことを通知します。これは定数変数の宣言や、オブジェクトの状態を変更しないことが保証されたメソッドに使用されます。

mutable は、constメソッド内でもクラスのフィールドの値を変更することを許可します。

volatile は、変数の値がプログラムの制御外で変更される可能性があることをコンパイラに通知します(たとえば、ハードウェアによって)、そのためコンパイラはそのアクセスを最適化してはいけません。

コード例

class Logger { public: void log() const { ++count; // 許可されている — count は mutable として宣言されている } private: mutable int count = 0; }; volatile int flag; void wait() { while (flag == 0) { /* コンパイラはループを最適化しない、なぜなら flag は volatile である */ } }

トリッキーな質問

「クラスメンバーを同時に constmutable として宣言した場合、どうなりますか?」

回答: それはできません、それは相互排他的な修飾子です;コンパイラはエラーを出します。


このテーマの微妙な点を知らなかったための実際のエラーの例。


事例

産業用ソフトウェアで外部割り込みによって更新されるデータを通常の int として宣言した開発者がいました。コンパイラの最適化により、これらの変数への繰り返しの読み取りが削除されたため、プログラムは「ハング」しました。この問題は volatile int に置き換えることで診断できました。


事例

あるロギングクラスには log() const メソッドがあり、呼び出し回数をカウントする必要がありました。最初は const_cast ポインタを使用して行っていたため、多くの警告や不明なバグを引き起こしました。問題は適切にカウントを mutable で宣言することで解消しました。


事例

いくつかのメソッドは const として宣言されていましたが、ポインタ型のメンバーを変更していました(例えば、キャッシュの実装のため)。これは「const-correctness」の論理を損ない、オブジェクトが実際に読み取り専用の領域に配置される場合には未定義動作(UB)さえ引き起こしました。mutable を使用するか、設計を変更する必要がありました。