2

私が取り組んでいるプロジェクトでは、次のように実装したかなり大きなテンプレート クラスがあります。

ヘッダーファイルがあります

// MyBigClass.h
#ifndef MYBIGCLASS_H
#define MYBIGCLASS_H

template <typename T>
class MyBigClass {
   /* -- snip -- */
};

#include "MyBigClass.cpp"
#include "MyBigClass_iterator.cpp"
#include "MyBigClass_complicatedFunctionality_1.cpp"
#include "MyBigClass_complicatedFunctionality_2.cpp"

#endif

そして、すべての実装ファイルは基本的に次のようになります。

// MyBigClass_foobar.cpp

template <typename T>
void MyBigClass<T>::member_1(){
   /* -- snip -- */
}

template <typename T>
int MyBigClass<T>::member_2(int foo, T & bar){
   /* -- snip -- */
}

// etc, etc

ではmain.cpp、 を含めるだけMyBigClass.hで、すべてが機能し、正常にコンパイルされます。実装を多くのファイルに分割した理由は、1200 行のファイル 1 つよりも、200 ~ 400 行の 3 つまたは 4 つのファイルで作業する方が好きだからです。ファイル自体はかなり論理的に編成されており、たとえば、ネストされたクラスの実装のみ、または相互に関連するメンバー関数のグループのみが含まれています。

私の質問は、これは行われたものですか? 先日、これを誰かに見せたときに奇妙な反応があったので、これが悪い習慣なのか、それともこのようなことを達成するためのより良い、より一般的な方法があるのか​​ 知りたいと思いました.

4

4 に答える 4

5

通常、ファイルをインクルードしないのが慣例cppです (これが行われる場合、限られた特殊なケースがあります)。

通常、この分離は、実装をファイルではなくファイルに移動することによって行わ.impl.hますcpp

いいえ、テンプレートの実装を分離し、ヘッダーにファイルを含めることに問題はありません。

于 2012-07-19T20:53:56.903 に答える
4

だから... include.cppは悪い習慣ですが、代わりにヘッダーファイルを使用できない理由は.cpp何ですか? .ippたとえばブースト使用ファイル...

于 2012-07-19T20:54:44.677 に答える
2

千以上のファイルを含む C/C++ プロジェクトに取り組んできたので、これは私が一般的に観察した慣行です。

  1. クラス定義をヘッダー ファイルに保持します。ヘッダー ファイルに実装を追加しないでください。インライン関数とテンプレートは例外です。私は最後にそれに行きます。
  2. すべての関数とメソッドの実装を .c または .cpp ファイルに保持します。

そうするのには根本的な理由があります。

  1. .h ファイルは、コードに実装したクラス/関数/ およびその他のデータ構造と API を使用するための参照ポイントとして機能します。クラス構造を知らない人は、最初に .h を参照します。
  2. 実際の実装を公開せずに、.h ファイルのみを公開するライブラリを配布できます。通常、彼らはライブラリ内の任意のコードへの唯一のエントリ ポイントであり、コードを共有したい場合にサード パーティが使用できる外部 API (これも .h ファイル) を考え出します。
  3. 複数の場所に .c または .cpp ファイルをインクルードすると、コンパイル中にエラーは表示されませんが、リンカーはシンボルの重複について不平を言います。含まれている .c/.cpp ファイルのすべての関数/メソッド部分の複数のコピーがあるためです。

例外

  1. インライン関数の実装を有効にするには、.h ファイルに存在する必要があります。コードの一部をインライン化できるとコンパイラが自動的に判断できる場合がありますが、場合によっては inline キーワードの存在が必要になります。注: ここでは後者についてのみ説明します。コンパイラは、inline キーワードがある場合にのみ関数をインライン化します。つまり、.cpp に次のコードが含まれている場合:

    クラスA; A.my_inline_method();

この cpp ファイルをコンパイルするときに my_inline_method() がインライン関数としてコンパイラに認識されない場合、この関数はインライン化されません。

  1. テンプレートは、コンパイルに関してはインライン メソッドに似ています。テンプレートのコードが使用される .cpp でコンパイラによって生成される必要がある場合、そのテンプレートの実装全体を知る必要があります。テンプレート コードの生成は実行時ではなくコンパイル時であるためです。

この背後にあるより一般的な哲学について言及しました。見逃した場合は、この回答を自由に編集して追加してください。

テンプレートの詳細については、こちら: テンプレートをヘッダー ファイルにのみ実装できるのはなぜですか?

編集:あいまいさを避けるために、@Forever のコメントに基づいて変更を加えました。

于 2012-07-19T21:09:32.810 に答える
1

テンプレート実装のやや標準的な拡張機能は.tcc. これは github の構文ハイライターによって認識さgccれ、 man ページにも記載されています。

C++ ソース ファイルでは、通常、接尾辞.C.cc.cpp.CPP.c++.cpまたは のいずれかを使用し.cxxます。C++ ヘッダー ファイルでは、、、、または (共有テンプレート コードの場合) がよく.hh使用さ.hppます.H.tcc

拡張機能の使用目的を誤解している場合は.tccお知らせください。この回答を削除します。

于 2012-07-27T02:26:08.077 に答える