C++のmutableキーワードとは?使い方とconstオブジェクトでの動作を解説
この記事では、C++におけるmutableキーワードの役割と使い方について詳しく解説します。
mutableは、C++における記憶クラス指定子(ストレージクラス)の一つです。mutableとして宣言されたデータメンバは、所属するオブジェクトがconst型であっても常に変更可能という特別な性質を持ちます。
「オブジェクト全体は定数として扱いたいが、特定のメンバ変数だけは変更できるようにしたい」というケースでは、そのメンバにmutableを指定することで柔軟に対応できます。キャッシュ値やロックフラグ、アクセス回数などの内部的な状態管理によく使われるテクニックです。
サンプルコード
以下の例を見て、mutableの動作を確認してみましょう。
#include <iostream>
using namespace std;
class MyClass{
int x;
mutable int y;
public:
MyClass(int x=0, int y=0){
this->x = x;
this->y = y;
}
void setx(int x=0){
this->x = x;
}
void sety(int y=0) const { // メンバ関数はconstだが、yは書き換え可能
this->y = y;
}
void display() const{
cout<<endl<<"(x: "<<x<<" y: "<<y << ")"<<endl;
}
};
int main(){
const MyClass s(15,25); // constオブジェクト
cout<<endl <<"Before Change: ";
s.display();
s.setx(150);
s.sety(250);
cout<<endl<<"After Change: ";
s.display();
}実行結果
[Error] passing 'const MyClass' as 'this' argument of 'void MyClass::setx(int)' discards qualifiers [-fpermissive]
このコードをコンパイルするとエラーが発生します。これは、constオブジェクトに対して非constメンバ関数であるsetx()を呼び出そうとしたためです。constオブジェクトからは、const修飾されたメンバ関数しか呼び出せません。
エラー行を削除して実行した場合
次に、「s.setx(150);」の行を削除してプログラムを実行すると、以下のようになります。
実行結果
Before Change: (x: 15 y: 25) After Change: (x: 15 y: 250)
解説:なぜyだけ変更できたのか?
実行結果に注目すると、xは15のまま変わっていませんが、yは25から250に更新されています。これがmutableキーワードの効果です。
- xは通常のメンバ変数のため、constオブジェクトでは変更不可
- yはmutable指定されているため、constメンバ関数sety()の中でも書き換えが許可される
つまり、mutableを付与したメンバは、constオブジェクトやconstメンバ関数内においても例外的に変更できるのです。この仕組みを活用すれば、オブジェクトの論理的な不変性を保ちながら、内部状態のみを柔軟に更新する設計が可能になります。
-
C++のautoキーワードとは?型推論の仕組みと使い方を徹底解説
C++におけるautoキーワードは、C言語から「引き継がれた」歴史あるキーワードでした。しかし、長い間ほとんど使われることはありませんでした。状況が大きく変わったのは、C++11でautoが「文脈から型を推論する」機能を持つようになってからです。C++11以前では、すべてのデータ型をコンパイル時に明示的に宣言する必要がありました。そのため、プログラマーは式の型を常に意識してコードを書く必要があり、特に複雑なイテレータ型などを扱う際には記述が冗長になりがちでした。しかし新しいバージョンのC++では、型推論をコンパイラ自身に任せられるキーワードが導入され、プログラマーの負担が大幅に軽減されました。
-
C++のconstキーワードとは?定数宣言の基本とメリットを解説
C++におけるconstは、変数を「定数」として宣言するための型修飾子です。const付きで宣言された変数は、一度初期化するとその値を後から変更することができません。 constを使うメリット constを使用する最大の利点は、プログラム内で値が意図せず書き換えられるのを防げることです。例えば、円周率(PI)のような不変の値を扱う場合、プログラムのどの部分からもその値が変更されないようにしたいはずです。このような値はconstとして宣言しておくことで、誤った代入から守ることができます。 コンパイラの最適化との関係 const修飾された型を持つオブジェクトは、コンパイラによって読み取り専用メ