コーディング規則
From Stellarium
今までに、プログラマーとして手伝ってくれる人の多くが、私たちのコーディング規則とそのガイドラインを明らかにするよう求めてきました。これまでの変遷によって、現在のStellariumのコードの全てがこの規則に従っているわけではありませんが、これからコードを追加・修正する場合は、以下の規則に従うようにしてください。
Contents |
文法や命名規則
- ソースコードには全てASCIIコードを使用してください。'é'や'ö'のような文字は、コードに直接書くと可搬性が下がります。そのような文字を使う場合は、gettextを利用すべきでしょう。
- 変数名やコメントは英語で書いてください。
- 特に普段日本語を使っている方は、意図せずに非ASCII文字を書き込んでしまう場合があります。常に日本語入力がオフになっているかに注意してください。
- クラス名は名詞を使い、最初の文字は大文字で、次に続く単語の先頭文字も大文字、それ以外は小文字という大文字小文字が混在した形になります(例:CoreFactory)。
- メソッド(メンバ関数)名は、大小文字混在の動詞もしくは名詞となります。常に小文字から始まります(例:update()やaddElement())。
- Methods that return a value should take the form getSize().
- ローカル変数名は、小文字から始まる大小文字混在の名前にします(例:packetSize)。これはメソッドの仮引数にも適用されます。下線(_)で始まる名前は使わないでください。
- マクロや静的で定数となるようなものの名前は全て大文字で書き、単語の区切りは下線を使います:
#define MIN_WIDTH 3 static const string VERSION = "0.8.2";
- インデント(字下げ)にはタブを使い、スペース(空白)は使いません。こうすることで、それぞれの開発者はコードを書き換えることなく、好みの文字数で字下げできるからです。
- 括弧は以下のレイアウトで使用してください:
void MyClass::myMethod(int x)
{
if (x>10)
{
cout << "You won." << endl;
}
}
- 空白行は次のように使用してください:
- メソッド間や(一行や複数行の)コメントの前には、1行あける
- メソッドの論理的に分かれている部分の間は、1行あける
- ソースファイルの中で別の項目間は、2行あける
ファイル名
C++のヘッダ/ソースファイルは.hpp/.cppの拡張子を、Cのヘッダ/ソースファイルは.h/.cの拡張子を付けてください。C++のファイルには、その中のクラス名と同じファイル名を付けてください。例えばStelFontMgrクラスはStelFontMgr.hppの中で宣言し、StelFontMgr.cppの中で実装されるべきです。
Doxygen用のコメント
StellariumのソースコードはDoxygenを用いて仕様書が作られています。DoxygenのWebサイトから引用すると:
"Doxygen is a documentation system for C++, C, Java, [...] It can generate an on-line documentation browser (in HTML) and/or an off-line reference manual (in LaTeX) from a set of documented source files. [...] The documentation is extracted directly from the sources, which makes it much easier to keep the documentation consistent with the source code. [...] You can also visualize the relations between the various elements by means of include dependency graphs, inheritance diagrams, and collaboration diagrams, which are all generated automatically.
翻訳すると:
"DoxygenはC++やC、Javaのための文書化システムです[...]。これはソースファイルから、自動的にオンライン用の仕様書(HTML)やオフライン用のリファレンス(LaTeX)を生成します。[...] この文書はソースから直接生成するので、常にソースコードを反映した文書を作成することが簡単にできます。[...] さらに、依存関係や派生図など、さまざまな要素の関係を、自動的に視覚化することもできるのです。
Stellariumで利用する、全てのpublic/protectedなクラスやメソッドはヘッダファイル(.hpp)の中に、完全な説明が書かれていなければなりません。
DoxygenがC++コードのコメントを参照するために、ヘッダファイルの中では次のように書きます:
//! Find and return the list of at most maxNbItem objects auto-completing the passed object I18n name. //! @param objPrefix the case insensitive first letters of the searched object. //! @param maxNbItem the maximum number of returned object names. //! @return a vector of matching object name by order of relevance, or an empty vector if nothing match. vector<wstring> listMatchingObjectsI18n(const wstring& objPrefix, unsigned int maxNbItem=5) const;
一番最初の概要は、最初のピリオドまで一行で簡潔に書きます。それ以降から@paramなどのタグの前までの文は、詳細な説明であると考えます。
メソッドの定義を.cppファイルの中でする場合、そのコメントはなるべくシンプルに書きます:
/*************************************************************************
Find and return the list of at most maxNbItem objects auto-completing the
passed object I18n name.
*************************************************************************/
vector<wstring> listMatchingObjectsI18n(const wstring& objPrefix, unsigned int maxNbItem=5) const
{
etc..
C/C++コード
C言語の関数は、すべてC++言語のそれに置き換えることが可能です。これには以下のようなものも含みます:
- char*の代わりにstd::stringを使います
- fopen()のようなC言語のファイル関数の代わりにC++のiostreamクラスを使います
- ポインタを使う代わりに、必要に応じて参照型(reference)を用います
- C++用の標準ヘッダをインクルードします。これはより可搬性があがります:
#include <stdio.h> // Bad #include <cstdio> // Good
- メモリリークを未然に防ぐために、不必要なポインタの利用を避けます。例えば:
string mapFileName = getDataDir() + "fontmap.dat"; ifstream *mapFile = new ifstream(mapFileName.c_str()); // Bad ifstream mapFile(mapFileName.c_str()); // Good
- std::vectorやstd::mapのようなSTLコンテナを利用します。これらは非常に効率的です。詳しいことはここを参考にしてください。
- グローバル関数やグローバル変数の利用を避けます。クラスの中にカプセル化したり、静的メンバ変数のような名前空間で用います。
- マクロの利用を避け、変わりにstatic constを使用します。これにより型の安全性がより増します。
#define RADIUS 12 // Bad static const int RADIUS = 12;
- 数学関数はC言語のものではなく、stdc++のものを使用します。これはより可搬性が多寡空、floatでオーバーライドされ、おそらく高速です。
double cosLat = cos(lat); // Bad double cosLat = std::cos(lat); // Good
文字列の翻訳と、コンソール画面への出力
Stellariumにおいて翻訳可能な文字列は、gettextのC++ラッパーであるTranslatorクラスを用いて翻訳されます。英語の文字列はstd::stringとして_()マクロに渡され、別の言語に翻訳されたのちstd::wstring(複数Byteの文字をサポートした文字列)として出力されます。
- ソースやデータ中の翻訳化の卯な文字列は、ASCIIもしくはUTF-8にエンコードされた英語として書かれている必要があります。
- 翻訳可能な文字列は、英語の慣例に従うべきです。たとえば、':'の前に空白を挿入すべきではありません
wstring myTranslatedText = _("Distance of the planet :") // Bad
wstring myTranslatedText = _("Distance of the planet:") // Good
- コードを修正する場合、本当に必要でない限り翻訳可能な文字列は変更しないでください。もし変更してしまうと、全ての言語の翻訳者がその新しい文字列を再翻訳する必要が生じるからです。
- 一般的に、コンソールに出力する文字列は翻訳すべきではありません(つまり、wstringにはしないということです)。なぜなら、通常の文字列と複数Byteの文字が出力されると、問題を生じる可能性があるからです。これは、wcoutやwcerr、wprintf()も使ってはいけないということを意味しています。コンソール出力は、普通の利用者があまり見ないような、情報やエラー、警告の出力に使うべきでしょう。
- エラーや警告は、標準出力ではなく標準エラー出力ファイルに出力してください。
cout << "Error while opening file " << myFileName << "." << endl; // Bad cerr << "Error while opening file " << myFileName << "." << endl; // Good
コードを自動的に整形する
astyleというプログラムを使えば、コードをここの規則に沿った体裁に整えることができます。以下のようなオプションを使用してください:
astyle --style=ansi -tU source.cpp
このコマンドは、source.cppというファイルを整形した形に置き換え、元のファイルをsource.cpp.origという名前で保存します。また、-Uオプション(丸括弧の前後の空白を削除)はastyleの最近のバージョンでのみ使用できます。

