4

初めて 1 つのプロジェクトで複数の C++ ファイルを使用しています。両方とも、保護された (#ifndef) ヘッダー ファイルを含める必要があります。ただし、それを行うと、複数定義エラーが発生します。

私が持っているのは、ヘッダーを直接呼び出す2つの.cppファイルと、間接的に1つ(別のインクルードに含まれています)、そしてそれを含む他の2つのヘッダーファイルです。

では、エラーを取り除くために何をする必要がありますか?

エラー:

obj\Debug\main.o||関数Z14sortLibQtyTest4BookS_':| [PATH]\miscFuncs.h|16|multiple definition ofで sortLibQtyTest(Book, Book)'

コード:

bool sortLibQtyTest(Book a, Book b){ return a.getQty() > b.getQty(); }

問題を引き起こしているのはこれだけではなく、おそらく 10 以上の問題があり、中にはそれほど短くて甘くないものもあります。また、関数は複数のファイルで必要です。

4

3 に答える 3

5

この複数定義の問題を解決するには、メソッドをインラインでマークするか、定義を .cpp ファイルに入れるという 2 つのオプションがあります。

1) メソッドをインラインでマークします。

// Foo.h

inline bool foo(int i) { return i = 42; }

2) 定義を.cppファイルに入れます。

// Foo.h

inline bool foo(int i); // declaration

// Foo.cpp
bool foo(int i) { return i = 42; } // definition

最初のケースでメソッドが実際にコンパイラによってインライン展開されるかどうかは、ここでは関係ありinlineません。1 つの定義ルールを破ることなく、ヘッダー ファイルで非メンバー関数を定義できます。

于 2013-07-15T05:07:35.817 に答える
3

".cpp" と ".h" の接尾辞は、ほとんど慣例の問題です。コンパイラに関する限り、コード行がどこから来たのかは関係ありません。その関数を .cpp ファイルに #include すると、その関数がその .cpp ファイルに実装されます。

そのため、コンパイラが完了し、2 つの cpp ファイルのコードを結合するようにリンカーに要求すると、競合が見つかります。同じ名前とフィンガープリント (引数と戻り値) を持つ 2 つの関数です。これはエラーです。

次のいずれかを行う必要があります。

を。実装を 1 つのソース ファイルに配置し、ヘッダーにプロトタイプ宣言を残すだけです

// .h
extern bool sortLibQtyTest(Book a, Book b);

// file1.cpp
bool sortLibQtyTest(Book a, Book b) { /* implementation */ }

b. 関数をインラインとしてマークします。関数を呼び出すと、コンパイラーは必要に応じて関数本体のコピーを挿入しますが、これは無駄になる可能性がありますが、多くの場合、コンパイラーは効率的な方法を見つけ出すことができます。

inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }

c. 関数を「静的」としてマークします。これにより、関数を含むすべてのソース ファイルに対して関数のコピーを作成するようにコンパイラに指示しますが、リンカーには公開しません。一部のソース ファイルに関数を使用せずにヘッダーが含まれている場合、コンパイラはこれを検出して削除する必要があります。これは、すべてのコンパイラ/最適化レベルで行われるわけではないため、二重に無駄になる可能性があります。

static bool sortLibQtyTest(Book a, Book b) {return a.getQty() < b.getQty(); }

d. c の欠点を回避し、静的インラインとしてマークします

static inline bool sortLibQtyTest(Book a, Book b) { return a.getQty() < b.getQty(); }
于 2013-07-15T05:20:43.097 に答える
1

「CODE」の後に引用した行がヘッダー ファイルにある場合は、次のいずれかを実行できます。

  • inline定義に追加するか、
  • ヘッダーから関数本体を削除し、ソース ファイルの 1 つ (1 つだけ) に配置します。
于 2013-07-15T04:51:43.213 に答える