2

私はC/C++ソースコードの非常に小さな部分に取り組んでいます。プログラムはstdinから入力値を読み取り、それらをアルゴリズムで処理し、結果をstdoutに書き込みます。

これらすべてを1つのファイルに実装するだけですが、アルゴリズムのテストケース(入出力の読み取りではない)も必要なので、プロジェクトには次のファイルがあります。

  • main.cpp
  • sort.hpp
  • sort_test.cpp

私はすぐにsort.hppにアルゴリズムを実装しますが、sort.cppは実装しません。かなり短く、依存関係はありません。

ヘッダーで定義された関数は、単純なアクセサー/ミューテーターではなく、高度なアルゴリズムであっても問題ない場合があると思いますか?それとも私がこれを避けるべき理由がありますか?いつコードをヘッダーからソースファイルに移動する必要がありますか?

4

8 に答える 8

8

トレードオフを理解している限り、ヘッダーファイルに関数を含めることに問題はありません。それらをヘッダーファイルに入れるということは、ヘッダーを含むすべての変換ユニットでコンパイル(および再コンパイル)する必要があることを意味します。(宣言するinline必要があります。そうしないと、リンカーエラーが発生します。)

多くの翻訳ユニットを使用するプロジェクトでは、多くの場合、コンパイル時間が著しく遅くなる可能性があります。

一方、関数が呼び出されるすべての場所で関数定義が表示されるようにします。つまり、簡単にインライン化できるため、結果のプログラムがより高速に実行される可能性があります。

そして最後に、関数テンプレートを使用すると、通常、現実的な代替手段はありません。定義は呼び出しサイトで表示される必要があり、それを実現する唯一の実用的な方法は、それをヘッダーに配置することです。

最後の考慮事項は、ヘッダーのみのライブラリは展開と使用が簡単であるということです。何かに対してリンクする必要はありません。ABIやその他のことについて心配する必要はありません。プロジェクトにヘッダーを追加し、それらを含めるだけで、すぐに使用できます。

かなりの数の人気のあるライブラリがヘッダーのみの戦略を使用しています。

于 2011-04-15T13:13:28.683 に答える
1

ヘッダーに関数があれば、それを入れてもかまいませんinline。内部で定義された関数class { }やテンプレートなどは暗黙的にinlineです。

結果のアプリケーションが大きくなりすぎる場合は、コードサイズを最適化します。問題が発生する前に最適化することはアンチパターンであり、特に「自分のやり方で」それを行うことに利点がある場合、修正はあるファイルから別のファイルに移動して消去するのと同じくらい簡単inlineです。

もちろん、コードをライブラリとして配布する場合は、ヘッダー、静的ライブラリ、または動的ライブラリバイナリのいずれかを決定することが、ユーザーに影響を与える重要な決定です。

于 2011-04-15T13:09:24.500 に答える
1

関数をヘッダーに配置するときは、必ずそれらを宣言する必要がありますinline。これは、複数の.cppファイルにそのヘッダーファイルが含まれている場合の重複定義の警告を回避するために必要です。通常、ヘッダーファイル内に小さな関数のみを配置する必要があります。これは、ヘッダーを含むcppファイルごとにコンパイルされるため、コンパイル時間が遅くなり、コードが膨張するためです。より大きな実行可能ファイル。

于 2011-04-15T13:13:08.880 に答える
0

それは本当に賢い選択です。しかし、それをヘッダーに入れることは、それが関数ではなくインラインコードになることを意味します。同じ機能が必要な場合は、インラインキーワードを使用できます。

inline int max(int a, int b)
{
  return (a > b) ? a : b;
}

http://en.wikipedia.org/wiki/Inline_function

于 2011-04-15T13:09:51.707 に答える
0

一般にこれを回避する必要がある理由(非インライン関数の場合)は、複数のソースファイルにヘッダーが含まれ、リンカーエラーが発生するためです。pramgaを一度持っているか、同様のトリックを持っているかは関係ありません。同じヘッダーを含む複数のコンパイルユニット(cppファイルなど)がある場合、重複が表示されます。

于 2011-04-15T13:11:49.853 に答える
0

Boostライブラリの大部分はヘッダーのみであるため、次のように言います。はい、これは確立され、受け入れられている方法です。忘れないでくださいinline

于 2011-04-15T13:15:49.243 に答える
0

関数をインライン化する場合は、ヘッダーに含める必要があります。そうでない場合、インライン化できません。

ライブラリを使用してヘッダーを公開し、ヘッダーに何らかの実装が含まれている場合、数年後に実装を変更しても、以前とまったく同じように機能しない場合は、一部の人々が確信できます。ヘッダーに表示された実装に依存するようになったため、コードが壊れます。ええ、私はそれをすべきではないことを知っていますが、多くの人々は、彼らが抱えている問題を克服するために意図しない方法で悪用/使用できる実装やその他の動作をヘッダーで調べます。

テンプレートの使用を計画している場合は、すべてをヘッダーに入れる以外に選択肢はありません。(コンパイラがエクスポートテンプレートをサポートしている場合、これは必要ないかもしれませんが、私が知っているのは1つだけです)。

于 2011-04-15T13:17:06.123 に答える
0

ヘッダーに実装があっても大丈夫です。それはあなたが必要とするものに依存します。定義を別のファイルに分離する場合、ヘッダー自体の内部で関数を定義できるようにしたくない場合は、コンパイラーは外部リンケージを使用してシンボルを作成します。しかし、コードセグメントのためにいくらかのメモリを浪費することになります。このヘッダーファイルを2つの異なるファイルにインクルードすると、両方のファイルコードセグメントにこの関数定義が含まれます。

他のヘッダーファイルに同じような名前の関数がある場合は、問題になります。次に、インラインを使用する必要があります。

于 2011-04-15T13:28:28.053 に答える