C++の勉強その4

平山先生の本は終わり。数学的なもの、メモリ周りは唸る部分も多かったが、やっぱりコードの保守性が考え方がだいぶ違うなあ。演算子書き換えまくったり。演算子のオーバーロードなんてフレームワーク書くとかじゃないとやりたくない。ゲームプログラマ特有のものかしらん。ブラックボックスな標準ライブラリ使う位ならO(n)かO(log n)じゃい! みたいのもちょっと気になった。

僕のゲームは2Dなので衝突とNPC AIだけ気にすれば多分大丈夫だろう。

さてさて、次はC++系Web資料にざっと目をとおしていく。終わったらcocos2d-x資料に目を通してhello worldの予定。

C++編【標準ライブラリ】

http://ppp-lab.sakura.ne.jp/cpp/library/index.html

  • 標準ライブラリの勉強。STLも標準ライブラリの一部らしい
  • 前のが通らなかったのは規格が違うかららしい

というかXcodeから入れたgccコンパイラのバージョンいくつなの?

~ $ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 7.3.0 (clang-703.0.31)
Target: x86_64-apple-darwin15.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

あれ。Xcodeから入ったのはgccじゃなくてclang?
ちょっと良くわからないのでc++11のコードを書いて通してみる。

//test.cpp
#include <iostream>
using namespace std;
class C {
        int i;
        public:
        C (int ia) : i(ia) {}
        C () : C (123) {}
 };
int main(int argc, char const* argv[])
{
        C c;
        return 0;
}
~$ g++ test.cpp
test.cpp:7:16: error: delegating constructors are permitted only in C++11
        C () : C (123) {}
               ^
1 error generated.

Wikipedia: C++11 を参考に
http://kaworu.jpn.org/cpp/C++11

~$ clang++ test.cpp -std=c++11
~$

通った。


Xcode 4 でデフォルトになった LLVM って何?
http://blog.fenrir-inc.com/jp/2011/07/llvm.html

違うものなのか。。mac/winでコンパイル予定だけど何か不具合があるといやだなあ。まあその時はgccを単独で入れよう。とりあえずc++11でかければいいや。というわけで、ドキュメントに戻る。STLに関しては合わせて以下も読む。

[C++] STLの型の使い分け
http://qiita.com/h_hiro_/items/a83a8fd2391d4a3f0e1c

  • mapはバイナリツリーでunorded_mapはチェイン法で実装されている。昔チェインハッシュ自分で書いたなぁ…(2度と書きたくない)
Let's Boost

http://www.kmonos.net/alang/boost/

正規表現、日付、シリアライズ(&デシリアライズ)、スレッド、乱数その他。

C++ビギナーに捧ぐ EffectiveC++入門

http://www002.upp.so-net.ne.jp/ys_oota/effec/

Effective-C++を買って読むと全然進みそうにないのでコチラをナナメ読み

  • クラスインターフェースはできる完全かつ最小限になるまで、よく設計を吟味する
    • んー。インターフェイスを機能で分けたほうが実装側の保守性があがるし…トレードオフじゃないかな
  • 関数内で new したオブジェクトのリファレンスを返してはいけない
    • main以外で作ったものは全部全部deleteしなきゃならないみたいな話になるんじゃないのか。気持ちは分かるけど
Google C++スタイルガイド 日本語訳

http://www.textdrop.net/google-styleguide-ja/cppguide.xml

だいたいこれに沿って書こうと思う。

  • 関数内で使う変数は、できるだけスコープを限定してください。そして宣言時には変数を初期化してください
  • 一般的にコンストラクタでは、メンバ変数の初期値の設定だけをするべきです。複雑な初期化をする場合には、明示的に Init() メソッドを使うべきです
  • 引数が1つのコンストラクタにはC++の explicit キーワードを付けてください
  • struct はデータを運ぶ受動的なオブジェクトだけに使ってください。それ以外にはすべて class を使ってください
  • たいていの場合、継承よりもコンポジションを使った方が適切です。継承を使うときには、public 継承にしてください
    • これは判断がイロイロ難しい
  • 特殊な状況を除き、演算子をオーバーロードしてはいけません
  • ポインタが本当に必要になったときには scoped_ptr を使いましょう。オブジェクトのオーナーシップを本当に共有する必要があるとき(たとえばSTLコンテナの内部)には、非constの std::tr1::shared_ptr を使うべきです。auto_ptr を使ってはいけません
    • どうなんだろう。生ポインタじゃダメかな…。書きながら検討
  • ファイル名はすべて小文字にするべきです。アンダースコア(_)やダッシュ(-)を含んでも構いません
  • 型名は大文字で始めて、単語の頭文字を大文字にして、アンダースコアを使わないようにしてください。MyExcitingClass、MyExcitingEnum など
    • enum は全部大文字で
  • 変数名はすべて小文字にして、単語と単語の間にはアンダースコアを入れてください。クラスメンバ変数はアンダースコアで終わるようにします。たとえば my_exciting_local_variable、my_exciting_member_variable_ など
  • 定数名k で始まり、大文字小文字で続けてください。たとえば kDaysInAWeek など
  • 通常の関数は大文字小文字の組み合わせにしてください。アクセサやミューテータは変数名と一致させてください。 MyExcitingFunction(), MyExcitingMethod(), my_exciting_member_variable(), set_my_exciting_member_variable()
    • キャメルケースのほうでいいかな
  • 名前空間名はすべて小文字で、プロジェクト名とできればディレクトリ構造に基づく名前にしてください。たとえば google_awesome_project など


とりあえずcpp関連の情報はここまで。