7

重複の可能性:
C++ のインライン関数

ヘッダー ファイルにクラスを完全に実装すると、コンパイラは何をしますか? 典型的な例は次のとおりです。

class MyException
{    
public:
    explicit MyException(const char* file, int line) file(file), line(line) {};
    const char* getFile() const { return file };
    int getLine() const { return line };
private:
    const char* const file;
    const int line;
};

私の意図は、次のようなクラスを使用することです: throw MyException(__FILE__, __LINE__).

このヘッダー ファイルを各 .cpp ファイルに含めます。コンパイラは、定義されている回数だけクラスをコンパイルし、生成するすべてのオブジェクト ファイルに (同一の) マシン コードを含めると思います。さて、リンカーは何をするでしょうか?私はより簡単な例を(それらの厄介なものをすべて除いてconst)試してみましたが、うまくコンパイルされました。

単純なクラスの代わりに、3 画面分の長さの C 関数をヘッダー ファイルに実装するとどうなるでしょうか。最後の質問ですが、例を .h ファイルと .cpp ファイルに分割する必要がありますか?

4

3 に答える 3

5

すべてのメソッドはインライン メソッドになります。コンパイル全体で最小限の時間が失われる可能性がありますが、問題ありません。私の知る限り、発生する可能性のある唯一の問題は、静的な非コスト メンバー変数がある場合です。次に、その格納場所を割り当てる必要があります (必要に応じて定義と初期値を配置します) .cpp。そうしないと、複数の定義に関するリンカ エラーが発生する可能性があります。

CPPの機能しか持たないヘッダーのみのプロジェクトを見main()たことがありますが、それはかなりテンプレート化されていました。

于 2012-09-04T09:19:02.513 に答える
4

クラス定義自体はコードを生成しません。クラスのユーザーがどのようにレイアウトされているかを示すだけなので、クラスを操作するための適切なコードを生成できます。

コードを生成するのはクラスのメンバー関数です。クラス定義内でメンバー関数を定義すると、関数に暗黙のinline宣言が与えられます。

関数呼び出しは、次の 2 つの方法のいずれかでコンパイルおよびリンクできます。

(1) 末尾に RETURN アセンブリ命令を含む関数コードの 1 つのコピーをイメージに配置し、CALL アセンブリ命令を (パラメーターの受け渡しと戻り値の転送と共に) 呼び出しサイトに配置して、制御を移すことができます。このコードに。

また

(2) 関数実装の完全なコピーは、呼び出しサイトで関数呼び出し全体を置き換えることができます。

宣言された関数inlineは、2 番目の方法で実行するようコンパイラに推奨します。さらに、inline宣言により、関数を複数の翻訳単位で定義できます (したがって、共有ヘッダー ファイルに配置できます)。コンパイラが 2 番目の方法を実装するオプションを持つためには、コンパイル時に関数実装のコピーが必要です。関数の実装が外国の翻訳単位にある場合、これは使用できません。

また、最新のコンパイラは、インラインで宣言された関数を使用して複雑なことを行うことにも注意してください。見る:

http://gcc.gnu.org/onlinedocs/gcc/Inline.html

于 2012-09-04T09:18:21.277 に答える
4

ヘッダー ファイル内にメンバー関数を実装すると、それらの関数はすべて暗黙的に になりinlineます。

これは何を意味し、どのような影響がありますか?

C++03 標準 §7.1.3/4 に従って:

  • これは、呼び出し時点での関数本体の置換が通常の関数呼び出しメカニズムよりも望ましいことをコンパイラーに示唆します。
  • インライン置換が省略された場合でも、インラインの他のルール (特に 1 つの定義ルール) に従います。

はい、すべての翻訳単位にはinline関数の定義があります。これにより、バイナリのサイズが増加する可能性があります。

通常、優れた主流のコンパイラは、必要に応じて呼び出し時点で関数本体を置き換えます。そのため、単に #1 の関数をマークすることは実際には良い考えではありませんが、クラスのユーザーに意図を明確にしinlineたい場合は、次のようにすることができます。ヘッダー内で関数を定義するか、関数を として明示的にマークします。inline

例をファイルに分割する必要が.hあり.cppますか?

はい、これはほとんどのプロジェクトが使用する通常のコンパイル モデルであり、実装 (.cpp) からインターフェイス (.h) を分離します。実装が提供されている間、インターフェイスはヘッダー ファイルとしてコードのユーザーと共有されます。これにより、ある程度、知的財産が保護されます。
これは分離モデルとして知られています。

テンプレートを使用する C++ プロジェクトは通常、通常の C++ プロジェクトの分離モデルではなく、包含モデルを使用します。

于 2012-09-04T09:57:16.393 に答える