はじめに
Effective C++ 第3版の3項9ページから勉強していきます。
今回は、「関数の引数にconst」についです。
Effective C++ 第3版 - 3項 可能ならいつでもconstを使おう -
関数の引数にconst
const修飾子をつける位置
前回の投稿で、
const修飾子がアスタリスク(*)の左にあるときには、「ポインタが指し示すデータ」が不変、
const修飾子がアスタリスク(*)の右にあるときには、「ポインタそのもの」が不変となると書きました。
int x = 5;
int x2 = 3;
// const修飾子がアスタリスク(*)の左
const int *p2_x = &x; // ポインタは非const
// データはconst
*p2_x = x2; // コンパイルエラー
p2_x = &x2;
// const修飾子がアスタリスク(*)の右
int *const p3_x = &x; // ポインタはconst
// データは非const
*p3_x = x2;
p3_x = &x2; // コンパイルエラー
そのため「ポインタが指し示すデータ」を不変とする場合、
const修飾子は、型名の前に付けても後(アスタリスクよりは前)に付けても問題ない。
// const修飾子を、引数の型(int 型)の前に付けた場合
void func1(const int *a) { // ポインタは非const
// データは非const
int b = 5;
*a = b; // コンパイルエラー
a = &b;
}
// const修飾子を、引数の型(int 型)の後に付けた場合
void func2(int const *a) { // ポインタは非const
// データは非const
int b = 5;
*a = b; // コンパイルエラー
a = &b;
}
そのため、上のコードは同じ引数型を持つ関数となる。
以下に、勉強で使用したコードを示します。
サンプルコード
3_const_tutorial2.cpp
# include <iostream>
void func1(const int *a) {
int b = 5;
// *a = b; // コンパイルエラー
a = &b;
}
void func2(int const *a) { // データはconst, ポインタは非const
int b = 5;
// *a = b; // コンパイルエラー
a = &b;
}
void func3(int *a) {
std::cout << a << std::endl;
*a = 11;
}
int main(int argc, char *argv[]) {
std::cout << "3_const_tutorial2.cpp" << std::endl;
int x = 3;
int *px = &x;
func1(px);
func2(px);
}
実行結果
参考文献
・https://www.amazon.co.jp/gp/product/4621066099/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0