C++ のポインターで const 修飾子を使用する

胡金庫 2023年10月12日
  1. C++ で読み取り専用オブジェクトを宣言するために const type var 記法を使用する
  2. C++ で読み取り専用オブジェクトを扱うためにポインタを用いて const 修飾子を使用する
C++ のポインターで const 修飾子を使用する

この記事では、C++ でポインタを用いて const 修飾子を使用する方法について、複数の方法を示します。

C++ で読み取り専用オブジェクトを宣言するために const type var 記法を使用する

C++ では、読み取り専用(不変)として定義する必要のあるオブジェクトの修飾子として const というキーワードを提供しています。const 変数は const type var または type const var という表記法で宣言されますが、どちらも構文的には正しいのですが、前者が従来のスタイルとして用いられます。const の修飾オブジェクトは変更ではないので、宣言の間に初期化されなければなりません。これにより const int number; - は無効になり、コンパイラエラーが発生します(おそらくあなたの IDE もそれについて悲鳴を上げるでしょう)。

変数 const が初期化されると、実行時に別の値を代入することはできません。したがって、次の例の main 関数の 3 行目は無効であり、コンパイラはこれを処理しません。同じ型の変数へのポインタを宣言した後に const 変数のアドレスをそれに代入しようとすると、コンパイラによってエラーが報告されることに注意してください。後者のエラーは、-fpermissive フラグを指定してコンパイルした場合、通常はオーバーライドされることに注意してください。

#include <iostream>

int main() {
  const int number = 1234;

  number = 235;        // Error
  int *ptr = &number;  // Error

  return 0;
}

C++ で読み取り専用オブジェクトを扱うためにポインタを用いて const 修飾子を使用する

const 修飾子はポインタと一緒によく使われます。宣言には const type * vartype *const varconst type *const var の三種類があります。1つ目は、var ポインタを読み取り専用の type オブジェクトへの var ポインタとして宣言するもので、オブジェクトは変更できないがポインタ自体は変更できることを意味します。2つ目は var 読み取り専用の type オブジェクトへのポインタであり、ここでは一意であり、変更可能なオブジェクトへの不変のポインタを宣言し、最後のものはポインタとオブジェクトの両方を不変であると定義しています。

これらの表記法は複数の有用な機能を提供し、以下のコードサンプルで説明します。最後の例で示されているように、const 変数のアドレスを const 以外のポインタに格納することはできませんでしたが、const 指定子を追加すれば操作は有効になります。しかし、main ループの 4 行目で示されているように、新たに宣言されたポインタを介して格納された値を変更することはできないことに注意してください。

#include <iostream>

using std::cout;
using std::endl;

#define STR(num) #num

int main() {
  const int number = 1234;

  const int *c_ptr = &number;
  //    *c_ptr = 42; // Error

  cout << STR(number) << " - " << number << endl;
  cout << STR(*c_ptr) << " - " << *c_ptr << endl;

  return 0;
}

出力:

number - 1234
*c_ptr - 1234

ポインタで const 修飾子を使っている間のもう一つの共通の問題は、読み込み専用のオブジェクトを指すポインタへの非 const ポインタの代入です。次のコード例では新しい nonconst 変数 number2 が初期化されており、const オブジェクトへのポインタとして宣言されていた c_ptrnumber2 のアドレスで代入されていることに注意してください。この操作は C++ では有効であり、結果として number2 変数に格納されている値を c_ptr を介してのみ読み込むことができますが、変更を加えるとコンパイラエラーが発生します。

#include <iostream>

using std::cout;
using std::endl;

#define STR(num) #num

int main() {
  const int number = 1234;
  const int *c_ptr = &number;

  int number2 = 3456;
  c_ptr = &number2;
  //    *c_ptr += 12; // Error
  number2 += 12;

  cout << STR(number) << " - " << number2 << endl;
  cout << STR(*c_ptr) << " - " << *c_ptr << endl;

  return 0;
}

出力:

number2 - 3468
*c_ptr - 3468
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C++ Const

関連記事 - C++ Pointer