MyEnigma

とある自律移動システムエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

Google C++スタイルガイドを読んで気がついたこと

はじめに

下記のリンク先にGoogleのC++のスタイルガイドの日本語訳があります。

ttsuki.github.io

個人的にはC++を一番使うのですが、

読んでみると当たり前だと思えることもありますが、

知らなかった便利な部分も多いので、

メモとして残しておきます。

1. グローバル変数の代わりに無名名前空間を使う

そのファイルのみで使用可能なグローバル変数や関数を使いたい時に、

staticを使うことは知っていましたが、

これはC言語的な書き方で、C++では無名名前空間を使うようです。

今度試してみたいと思います。

無名名前空間

2. クラス型のstatic or global オブジェクトは使わない

staticなクラスオブジェクトを結構使っているので、

ビックリしました(笑)。

禁止している理由は、オブジェクトの生成と解放の順序が不定であり、

発見困難なバグにつながるためのようです。

代わりに、mainの最初の時にnewして実体化することが勧められています。

3. 引数が1つのコンストラクタには explicit キーワードを付ける。

これも知りませんでした(笑)。

コンストラクタが引数一つの場合、

イコールで値を代入するコードを書いてしまうと、

それが勝手にコンストラクタであると判断されて、

オブジェクトが生成されてしまうということです。

これを防ぐためにはexplicitをコンストラクタの前に付ける必要があります。

(でも、そもそもこの暗黙の呼び出しが不要なのでは。。)

引数1個のコンストラクタの暗黙呼び出しとexplicit

コンストラクタ

4. ポインタを使う場合は、boost::scoped_ptr or unique_ptrを使う

boostを殆ど使っていないので、知らなかったのですが、

この型をポインタに使うと、

自動的にdeleteしてくれるようです。

ガーベージコレクションのようなものでしょうか。

リソースを自動的に解放する - boostjp


またC++11からは、このspoed_ptrもunique_ptrという形でBoostではなく、

標準のC++の機能に追加されたらしいので、C++11の機能を使える方は、

unique_ptrを使用した方がいいと思います。

unique_ptr (C++11) - cpprefjp - C++ Library Reference

5. 関数の入力はconst リファレンス, 出力はポインタとする。

これまで自分は入力はconstリファレンスにしていましたが、

出力はリファレンスにしていました。

コールドリーディングする際に、

関数の出力がポインタに記法によって目立つのでわかりやすいかもしれません。

今度から使ってみたいと思います。


6. デフォルト引数は使わない

そもそもデフォルト引数という存在をしらなかった。。。。(笑)

まあ、使わない方が良いなら知らなくても良いのでしょう。

7. キャストする時はC++のものを使う

ずっとC言語のキャストを使っていました。。。

C++では4種類のキャストがありますが、

おそらくstatic_cast以外は使わないと思うので、

今度からはstatic_castを使いたいと思います。

C++のキャスト演算子

8. イテレータのインクリメントは前置インクリメントにする

STLを使っているとイテレータを使わざるおえませんが、

後置インクリメントよりも、前置インクリメントの方が、

パフォーマンスが良いなんて知りませんでした。。。

STLを使ったソフトをすべて書き直したいです(笑)

9. 固定長の変数を使いたい場合は or をインクルードしてその中の型を使う

自分は半分組み込みエンジニアなのですが、これも知りませんでした (恥)

これまでは無理やりtypedefしていましたが、

これからはstdint.hの型を使うつもりです。

stdint.h


またC++11ではstdint.hのC++版であるが導入されました。

内容はstdint.hと殆ど同じのようですが、

名前空間などC++との親和性が高いので、

C++11が使える場合はこちらを使うと良いかと思います。

cstdint (C++11) - cpprefjp - C++ Library Reference



もう一つ驚きだったのが、同じ項で説明されている

Unsignedを使うなという話です。

Unsignedを使うなら、signedを使って負の値をアサーションするように薦めています。

ただ、一般的なコンパイラオプションでは、配列のインデックスにアクセスする時に、

signedの値でアクセスするとWarningが出る気がするのですが。。。

10. OSの32/64bitのソフトの分岐には#ifdef _LP64を使う

これも知らなかったです。

ただできるだけ使わないようにするのは当然ですね。

おわりに

もう7年ほどC++を使っていますが、知らないことばかりで泣きそうです(;´Д⊂)(笑)

コメントにて上級者の方に冒頭の本を紹介されたので、

これらを読んで精進したいと思います。

MyEnigma Supporters

もしこの記事が参考になり、

ブログをサポートしたいと思われた方は、

こちらからよろしくお願いします。

myenigma.hatenablog.com