C++ バイト先で学んだこと-2
今回も学んだことまとめます。
・生ポインタ使わない
複数人でコードを書くときは、生ポインタではなくシェアードポインタを使う。あたりまえかもですが一応...
・ちょっとした関数を作るときは無名名前空間を使う。
あるクラスとかでちょっとした関数を作ったときに、ヘッダーに宣言を書くといろいろ問題になる可能性があるらしい。そういう時は無名名前空間を使います。これはそのファイル内でしか見ることができないネームスペースだから、他のところで再定義されたりすることがなくなります。
//unnamed namespace namespace { void Test() { } }
・constポインタ
const int a = 0; //値がconst const int* p = nullptr; //ポインタの値がconst int* const q = nullptr; //ポインタの場所がconst const int* const c = nullptr; //値もポインタもconst int b = 0; a = 2; //ダメ p = &b; //良い *p = b; //ダメ q = &b; //ダメ *q = b; //良い c = &b; //ダメ *c = b; //ダメ
ここで疑問に思ったのがポインタのconstなんていつ使うのかということです。値がconstは、const関数内とかでたまにconstじゃないときがあるから。
class A { public: A() :test(0) {} int test; }; class B { public: B() : a(), p(std::make_shared<A>()) {} A a; std::shared_ptr<A> p; void set()const { a.test = 1;//ダメ p->test = 1;//できちゃう } };
ポインタの場所がconstの必要性について
調べたけどあんまり解説がなかったので先輩に聞きました。
結論から言うとそれほど必要!って感じではないけど、インターフェースとしてある方が良いという感じです。
ここでいうインターフェースとは、そのクラスや関数を使う人からどう見えるかという意味です。
関数の引数がconst参照だった場合は中で変更がないことを意味していて、非constなら変更があるかもしれないという意味になります。
ちなみに参照じゃない場合はinputにしか使わないということになるのでconstはそもそも必要ありません。使う側からしたらどちらも同じです。
//この二つはconstだろうとそうじゃなかろうとvalは変更されない void func(int val){} /*1*/ void func(const int val){} /*2*/ //これは値が変わるかも void func(MyClass& ins){} /*3*/ //これは値が変わらないことを意味している void func(const MyClass& ins){} /*4*/
※ここで4番の関数と1と2は一緒の意味だから全部1でいいじゃんって思うかもしれません。上でも説明したように1と2は同じですが、4は違います。4は参照を使っていますが、これは無駄なコピーコストをなくすためです。
あとはconstということは確実に何らかの値が入っていることが保証されています。初期化忘れがないのは大事です。
そんなわけでポインタの場所がconstにズバリこれ!といった意味はありません。(もしかしたらあるかもしれないけどぼくの周りにはわかる人いません)
どっか間違ってたら教えてください>