【C++】constとvolatileの使い分け | cv修飾子を徹底解説

目次

はじめに

C++で変数を宣言する際、int x; のように型を指定するだけでなく、constvolatile といった修飾子を付け加えることができます。これらは、その変数がどのように扱われるべきかをコンパイラとプログラマに伝えるための重要なキーワードです。

  • const: その変数が変更不可能な「定数」であることを示す。
  • volatile: その変数が予期せず変更される可能性があることを示し、コンパイラによる最適化を抑制する。

この記事では、これら2つのcv修飾子の意味と、それぞれの正しい使い方を解説します。


1. const: 変更不可能性

const (constantの略) は、一度初期化されたら、その後値が変更されることのない変数(定数)を宣言するために使います。

const変数

constを付けて宣言された変数は、再代入しようとするとコンパイルエラーになります。

const int MAX_USERS = 100;
// MAX_USERS = 200; // エラー! const変数は変更できない

constポインタと参照

constはポインタや参照と組み合わせることで、より細かい制御が可能になります。

int value = 10;

// 1. ポインタが指す先の値を変更できない (constへのポインタ)
const int* p1 = &value;
// *p1 = 20; // エラー!
p1 = nullptr; // OK: ポインタ自体は変更可能

// 2. ポインタ自体を変更できない (constポインタ)
int* const p2 = &value;
*p2 = 20; // OK: 指す先の値は変更可能
// p2 = nullptr; // エラー!

// 3. 両方とも変更できない
const int* const p3 = &value;

// 4. const参照
const int& ref = value;
// ref = 20; // エラー! 参照経由での変更はできない

constメンバ関数

クラスのメンバ関数の後ろにconstを付けると、その関数がオブジェクトのメンバ変数を変更しないことを約束します。constオブジェクトからは、constメンバ関数しか呼び出せません。

class Player {
private:
    int hp_ = 100;
public:
    // constメンバ関数: メンバ変数を変更しない
    int getHp() const {
        return hp_;
    }
    // 非constメンバ関数: メンバ変数を変更する
    void takeDamage(int damage) {
        hp_ -= damage;
    }
};

int main() {
    const Player const_player;
    const_player.getHp(); // OK
    // const_player.takeDamage(10); // エラー! constオブジェクトからは非const関数は呼べない
    return 0;
}

2. volatile: 最適化の抑制

volatileは、constとは全く異なる目的で使われます。このキーワードは、「この変数の値は、プログラムのコードからは見えない要因(例: ハードウェア、別のスレッド)によって、いつでも変更される可能性がある」とコンパイラに伝えます。

これにより、コンパイラはその変数へのアクセスに関する最適化を抑制し、コードに書かれた通りのメモリアクセスを保証します。

サンプルコード

// volatile変数の例 (概念的なコード)

// 0x1234番地にあるハードウェアのステータスレジスタを指していると仮定
volatile int* status_register = (int*)0x1234;

// 最適化なし: ループのたびに、必ずメモリから値を読み直す
while (*status_register == 0) {
    // 待機
}

解説: もし volatile がなければ、コンパイラは「ループの中で status_register の値は変わらない」と判断し、最初の読み込みだけでループを最適化(無限ループ)してしまう可能性があります。volatile は、そのような最適化を防ぎ、毎回ハードウェアレジスタの値を正直に読みに行くように強制します。


まとめ

今回は、C++のcv修飾子 constvolatile について解説しました。

  • const: 不変性を保証し、プログラムの安全性を高めるために使う。constを積極的に使うのが良い習慣。
  • volatile: 最適化を抑制し、メモリへの直接的なアクセスを保証するために使う。主に組み込みシステムやデバイスドライバ開発など、非常に低レベルな場面で必要になる。

一般的なアプリケーションプログラミングで volatile が必要になることは稀ですが、const はプログラムの堅牢性を高めるために日常的に使うべき、非常に重要なキーワードです。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次