4. プロジェクトの構成

4.1. ソースコードの構造

4.1.1. 規約事項 2

C++のヘッダファイル名には、拡張子.hを使用してください。

4.1.2. 規約事項 3

C++の実装ファイル名には、拡張子.cppを使用してください。

4.2. ファイルの命名

4.2.1. 規約事項 4

ファイル名は、できるだけ大きな範囲で一意となる名前にしてください。 クラスのヘッダファイル名は、<クラス名>+.hとしてください。 クラス名には、ソースコードと同じとなるよう、大文字と小文字を使用します。 一般的に、クラス名は大きな範囲で一意となるよう命名されるため、 ヘッダファイルを命名する際にもこの特性を利用するのが適切です。 ヘッダファイル名をクラス名と同一にすることで、クラス定義を簡単に見つけることができます。

4.3. プロジェクトの構造

4.3.1. 規約事項 5

すべてのプロジェクト(ライブラリまたはアプリケーション)には、明確な構造の独自のディレクトリを用意してください。 プロジェクトディレクトリには、プロジェクトファイル、メイクファイル、ヘッダファイル、実装ファイル、 ドキュメント、テストスイート用の他のディレクトリを含めることができます。 図1は、プロジェクトのディレクトリ階層を示しています。

テストスイートは、それ自体がプロジェクトであり、testsuiteディレクトリ内に プロジェクトディレクトリと同じ構造を持っています。 ただし、テストスイートにはパブリックヘッダファイルがないので、 テストスイートディレクトリ内にインクルードディレクトリはありません。

4.3.2. 規約事項 6

パブリックヘッダファイルは常にincludeディレクトリまたは そのサブディレクトリに格納されます。ネームの衝突を避けるため、 およびよりわかりやすいように、includeディレクトリに サブディレクトリを含めることができます。ライブラリの場合、 includeディレクトリには通常、ライブラリと同じ名前の サブディレクトリが含まれます。

4.3.3. 規約事項 7

実装ファイルとパブリックでないヘッダファイルは、 srcディレクトリに格納されます。

4.3.4. 規約事項 8

プロジェクトファイル、メイクファイル、 およびソースコードを含まないその他のサポートファイルは、 プロジェクトディレクトリに直接格納します。

4.3.5. 推奨事項 4

プロジェクトに関する追加のドキュメント (仕様書や標準ドキュメントなど)がある場合、 このドキュメントはdocというディレクトリに移動します

4.4. 空白

4.4.1. 規約事項 9

ヘッダーおよび実装ファイルでは、冒頭コメント、インクルードガード、 #includeブロック、usingブロックおよび関数定義を2つの空行で区切ります。 これにより、様々な要素を視覚的に区別しやすくなります。

4.4.2. 規約事項 10

実装ファイルまたはヘッダファイルの最後の行は 改行で終わらなければなりません。 ほとんどのコンパイラでは問題となりませんが、 C++規約で定められています。

4.5. コメント

4.5.1. 規約事項 11

ソースコードを含むすべてのファイルは、ファイル名、バージョン、 および内容に関する情報を含むんだ冒頭コメントを記載する必要があります。

4.5.2. 規約事項 12

すべてのファイルに、著作権情報が含まれている必要があります。

4.5.3. 規約事項 13

すべてのコメントは、英語で記載される必要があります。

4.5.4. 規約事項 14

すべてのクラス、public / protected関数、public / protected enum / typedef / struct のコメントを書いてください。コメントの標準化により、 ソースコードからリファレンスドキュメントを自動的に生成することができます。 これはソースコードとドキュメントを最新の状態に保つために使用されます。 これらのコメントのフォーマットは、付録で説明されています。

4.5.5. 規約事項 15

コメントには//を使用します。 ソースコードを文書化する必要があります。これはコンパクトで見つけやすいはずです。 変数、関数、クラスの名前を適切に選択し、コードを適切に構造化することで、 コード内のコメントが少なくてすみます。

ヘッダーファイル内のコメントはクラスのユーザー向けのコメントであり、 実装ファイル内のコメントはクラスを維持するユーザー向けのコメントであることに注意してください。

私たちのコードはすべて著作権で保護されていなければなりません。 コードが何年にもわたって開発された場合は、毎年記述する必要があります。

コメントはしばしば戦略的か戦術的かのいずれかであると言われています。 戦略的コメントは、コードの機能またはセクションが何を意図しているのかを記述し、 このコードの前に配置されます。戦術的コメントは、1行のコードが何を意図しているのかを記述し、 可能であればこの行の最後に配置されます。残念なことに、戦術的コメントが多すぎると、 コードを読むことができなくなる可能性があります。このため、非常に複雑なコードを説明しない限り、 主に戦略的なコメントを使用することをお勧めします。

コメントを書くために//文字が一貫して使用されている場合は、開発/デバッグ段階でコメントの作成に / * * /を使用することができます。ただし、C ++では/ * * /を使用してコメントをネストすることはできません。 したがって、プリプロセッサ(#if 0 ... #endif)を使用してコードの大部分をコメントアウトする方が良いでしょう。 コメントアウトされたコードセクションを含むソースファイルは、そのコードを扱う他の開発者を混乱させるので、 SCMリポジトリにチェックインしないでください。

すべてのヘッダーまたは実装ファイルの先頭に含めるボイラープレートのテキストを以下に示します。

例1
//
// <FileName>.h
//
// $Id$
//
// Library: <LibraryName>
// Package: <PackageName>
// Module: <ModuleName>
//
// <One or two sentences describing what the header file is for. Can
// be omitted in source (.cpp) files.>
//
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
// All rights reserved.
//
// <License Notice>

4.6. ヘッダファイル

4.6.1. 規約事項 16

すべてのヘッダファイルには、複数回インクルードされることを防止する仕組みが含まれている必要があります。

4.6.2. 規約事項 17

以下の種類の定義が(インプリメンテーションファイルまたは他のヘッダーファイルで) 使用される場合、それらは別々のヘッダーファイルとしてインクルードする必要があります。

  • 基底クラスとして使用されるクラス
  • メンバ変数として使用されるクラス
  • 関数の戻り値として定義されたクラス
  • ファイル内のインラインメンバ関数で使用される関数定義

4.6.3. 規約事項 18

ポインタ(*)または参照(&)でしかアクセスされないクラスの定義は、 ヘッダファイルとして含まれていてはなりません。代わりに、前方宣言を使用してください。 唯一の例外は別の名前空間にあるクラスです。

4.6.4. 規約事項 19

#includeディレクティブでは、相対パス( ”.”と ”..”を含む)を決して使用しないでください。

4.6.5. 規約事項 20

すべての実装ファイルには、以下を含む関連ファイルがインクルードされている必要があります

  • ファイル内の関数で使用される型と関数の宣言
  • ファイル内の関数で使用される変数とメンバ関数の宣言

4.6.6. 規約事項 21

すべての実装ファイルは、他のヘッダファイルの前に、自身と対応するヘッダファイルを含める必要があります。 これにより、自身のヘッダファイルが自己完結していることが保証されます。

4.6.7. 規約事項 22

ユーザが用意したインクルードファイルには#include “filename.h”という指令を使用します。

4.6.8. 規約事項 23

#include <filename.h>は、システムおよびコンパイラが提供するヘッダファイルのみに使用します。

4.6.9. 規約事項 24

コンパイラインクルードパスは、常にプロジェクトディレクトリのインクルードディレクトリを指します。 したがって、ヘッダーファイルがインクルードディレクトリのサブディレクトリにある場合は、 #include “dir/filename.h”としてインクルードする必要があります。 これにより、異なるプロジェクトに同じ名前のヘッダファイルがあった場合でも、名前の衝突を避けることができます。

複数のインクルードファイルを避ける最も簡単な方法は、ファイルの先頭に#ifndef /#defineブロックを使用し、 ファイルの最後に#endifを使用する方法です。

含まれるファイルの数を最小限に抑える必要があります。ファイルがインクルードファイルに含まれている場合、 最初のファイルが変更されるたびに、2番目のインクルードファイルを含むすべてのインプリメンテーションファイルを再コンパイルする必要があります。 1つのインクルードファイルを単純に変更すると、多数のファイルを再コンパイルする必要があります。

ファイルに定義された型へのポインタや参照のみを参照する場合、そのファイルを含める必要はないことがよくあります。 クラスが存在することをコンパイラに通知するには、前方宣言を使用すれば十分です。 もう1つの選択肢は、クラスへのポインタの各宣言の前にキーワードclassを付けることです。

インクルードガードを使用して、ヘッダファイルの多重インクルードを防ぐ例を以下に示します。

例2
#ifndef Foundation_SharedPtr_INCLUDED
#define Foundation_SharedPtr_INCLUDED
#include "Poco/Foundation.h"
//...
#endif // Foundation_SharedPtr_INCLUDED