web-dev-qa-db-ja.com

メンバー関数の最後のconstの意味は何ですか?

C++のconstキーワードは、メンバー関数の最後(引数リストの後)に記述されている場合、正確にはどういう意味ですか?

65
Mat

だということだ *thisは、そのメンバー関数内のconstです。つまり、オブジェクトを変更しません。

キーワードthisはprvalue式であり、その値は関数が呼び出されるオブジェクトのアドレスです。クラスthisのメンバー関数のXの型はX*。メンバー関数がconstとして宣言されている場合、thisの型はconst X*。 [セクション9.3.2§1]

constメンバー関数では、関数が呼び出されるオブジェクトはconstアクセスパスを介してアクセスされます。したがって、constメンバー関数は、オブジェクトとその非静的データメンバーを変更しません。 [セクション9.3.2§2]

これは、クラスのconstインスタンスでconstメンバー関数を呼び出すことができることを意味します。 const以外のメンバー関数を呼び出すことはできません [1]潜在的に変更を試みる可能性があるため、constオブジェクト。

[1] 注:テンポラリは、const型でない限り、constオブジェクトではありません。

73

関数シグネチャの末尾のconstは、その関数がメンバーであるオブジェクトがconstであると想定する必要があることを意味します。実際には、コンパイラにcheckを要求することを意味します。メンバー関数がオブジェクトデータを変更しないようにします。これは、コンパイラにメンバーデータを直接変更しないことを確認するように依頼することを意味します。また、オブジェクトを変更しないことを保証しない関数自体は呼び出しません。

constオブジェクトを作成するとき、そのオブジェクトがその初期化を超えて変化しないことを確認するようコンパイラーに求めています。つまり、コンパイラは、メンバーデータを直接変更しないことをチェックし、オブジェクトが変更されないことを保証しない関数を呼び出さないことを意味します。

これはすべてconst correctness哲学の一部です。本質的に、それは、物事が今すぐ機能し、それらが変わらない場合、決して壊れないことを意味します。言い換えれば、一定のものは確実に作業しやすいです。関数シグネチャの最後にあるこのconstのことは、物事が壊れることを禁止するためのツールです。これは、可能な限りあらゆる場所にconstを配置する必要があることを意味します。

30
wilhelmtell

コンパイラーの最適化は可能ですが、主な利点は、関数の宣言で表されるコントラクトを実施することです-メンバー関数をconstとして定義すると、コンパイラーはその関数内のオブジェクトの変更を防ぎます。

宣言でmutableを使用して、クラス内の個々のフィールドをこの制限から除外できます。これは、たとえば、独自のlock_guardをカプセル化するクラスがあり、その値を変更してconstメンバー関数内でもスレッドセーフを適用する必要がある場合に役立ちます。

11
Steve Townsend