inline関数の使い方の詳細

4901 ワード

  • inline関数定義
  • インライン関数のプログラミングスタイル
  • 内連
  • を慎む
  • inlineと前処理の違い
  • 参考資料

  • inline関数定義
    関数宣言または定義で関数がタイプを返す前にキーワードinlineを付けてmin()をインラインに指定します.
          inline int min(int first, int secend) {/****/};

    inline関数は、呼び出しポイント内で関数を展開できるようにコンパイラに表示される必要があります.非inline関数とは異なり、inline関数は、その関数を呼び出す各テキストファイルで定義する必要があります.もちろん、同じプログラムの異なるファイルに対して、inline関数が現れた場合、その定義は同じでなければなりません.2つのファイルからCとdraw.Cで構成するプログラムでは,プログラマはこのようなmin()関数を定義することができず,compute.Cはdrawで1つのことを指します.Cはもう一つのことを指す.2つの定義が異なる場合、プログラムは未定義の動作をする.このようなことが起こらないことを保証するために、inline関数の定義をヘッダファイルに置くことをお勧めします.このヘッダファイルは、inline関数を呼び出す各ファイルに含まれます.この方法は、各inline関数に対して1つの定義しかなく、プログラマが必要とせず、プログラムのライフサイクル中に無意識の不一致を引き起こすことができないことを保証する.
    インライン関数のプログラミングスタイル
    キーワードinlineは、関数をインライン化するには、関数定義体と一緒に配置する必要があります.inlineを関数宣言の前に置くだけでは何の役にも立たない.次のようなスタイルの関数Fooはインライン関数にはなりません.
    inline void Foo(int x, int y); // inline           
    void Foo(int x, int y)
    {
    }

    次のようなスタイルの関数Fooは、インライン関数となります.
    void Foo(int x, int y);
    inline void Foo(int x, int y) // inline           
    {
    }

    したがって、inlineは「宣言用キーワード」ではなく「実装用キーワード」である.一般に、ユーザは関数の宣言を読むことができるが、関数の定義は見えない.ほとんどの教科書では、関数の宣言、定義体の前にinlineキーワードが付けられていますが、inlineは関数の宣言に現れるべきではないと思います.この詳細は関数の機能には影響しませんが、高品質のC++/Cプログラム設計スタイルの基本原則を体現しています.宣言と定義は混同してはいけません.ユーザーは関数がインラインする必要があるかどうかを知る必要はありません.inlineキーワードは、ユーザーが知る必要がないため、クラス宣言で定義されたメンバー関数が自動的にインライン関数になるかどうかを知る必要がないため、関数の宣言に入れなくてもよい.例えば、
    class A
    {
    public:
    void Foo(int x, int y) {  } //          
    }

    メンバー関数の定義体をクラス宣言に置くと、書くのに便利になりますが、良いプログラミングスタイルではありません.前例は次のように変更します.
    //    
    class A
    {
    public:
    void Foo(int x, int y);
    }
    //     
    inline void A::Foo(int x, int y)
    {
    }

    内連を慎む
    インラインは関数の実行効率を高めることができますが、なぜすべての関数をインライン関数として定義しないのですか?1.インラインは、コードの膨張(コピー)を代償として、関数呼び出しのオーバーヘッドを省くだけで、関数の実行効率を向上させる.関数内のコードを実行する時間が、関数呼び出しのオーバーヘッドよりも大きい場合、効率の収穫は少ない(一般的には、関数が頻繁に呼び出され、関数内のコードが少ない場合にインラインが使用される).各インライン関数の呼び出しは、プログラムの総コード量を増大させ、より多くのメモリ領域を消費します.3.内部接続は使用しないでください:(1)関数内のコードが長い場合、内部接続を使用するとメモリ消費コストが高くなります.(2)関数内にループが発生した場合、関数内のコードを実行する時間は、関数呼び出しのオーバーヘッドよりも大きくなります.クラスのコンストラクタとコンストラクタは、インラインを使用した方が効果的だと誤解されがちです.コンストラクタとコンストラクタは、「こっそり」などの動作を隠す可能性があることに注意してください.ベースクラスまたはメンバーオブジェクトのコンストラクション関数とコンストラクション関数が実行されます.したがって、クラス宣言にコンストラクション関数とコンストラクション関数の定義体を勝手に置かないでください.C++言語サポート関数のインライン、その目的は関数の実行効率を向上させることである(速度).良いコンパイラは関数の定義体によって、価値のないインラインを自動的にキャンセルする.Cプログラムでは、マクロコードで実行効率を高めることができる.マクロコード自体は関数ではないが、似たような関数を使用する.プリプロセッサは、関数呼び出しの代わりにマクロコードをコピーした方程式を使用し、パラメータスタックを省き、アセンブリ言語を生成するCALL呼び出し、参照を返す数、returnなどのプロセスを実行することで、速度が向上します.マクロコードを使用する最大の欠点は、エラーが発生しやすいことであり、プリプロセッサはマクロコードをコピーする際に予想外の境界効果を生じることが多い.C++の場合、マクロコードを使用すると、クラスのプライベート・データ・メンバーを操作できないというもう一つの欠点があります.C++の「関数インライン」動作方式:1.任意のインライン関数について、コンパイラはシンボルテーブルに関数の宣言(名前、パラメータタイプ、戻り値タイプを含む)を入れます.2.コンパイラがインライン関数にエラーがない場合、その関数のコードもシンボルテーブルに入れられます.インライン関数を呼び出すとき、コンパイラはまず呼び出しが正しいかどうかを確認します.(タイプセキュリティチェックを行ったり、自動タイプ変換を行ったりして、もちろんすべての関数に対して同じです).3.正しい場合、インライン関数のコードは直接関数呼び出しを置き換え、関数呼び出しのオーバーヘッドを省きます.
    inlineと前処理の違い
    1.このプロセスは、プリプロセッサがタイプセキュリティチェックを行うことができないか、または自動タイプ変換を行うことができないため、プリプロセッサとは著しく異なる.インライン関数がメンバー関数である場合、2.C++言語の関数インラインメカニズムは、マクロコードの効率性とセキュリティを向上させ、クラスのデータメンバーを自由に操作できるので、C++プログラムでは、すべてのマクロコードをインライン関数で置き換えるべきであり、「assertを断言する」ことはおそらく唯一の例外である.(assertは、Debugバージョンのみで機能するマクロであり、「不可」が発生した場合をチェックするために使用されます.プログラムのDebugバージョンとReleaseバージョンで差が生じないように、assertは副作用を生じるべきではありません.)assertが関数である場合、関数呼び出しによって内蔵、コードの変動が生じるため、DebugバージョンとReleaseバージョンに差が生じることになります.したがってassertは関数ではなくマクロです.
    参考資料
  • C++Primer第5版
  • 高品質C+/Cプログラミングガイド
  • http://blog.csdn.net/kekuixiong/article/details/6652254