C++プログラミングにおけるキューインライン関数の理解と使用
4359 ワード
関数呼び出しプロセスc++はコンパイルにより実行可能プログラムファイルexeを生成し、外部メモリに格納する.プログラムが起動し、外部メモリから実行可能ファイルをメモリにロードし、エントリアドレス(main関数の先頭)から実行します.プログラム実行中に他の関数の呼び出しに遭遇すると,現在の関数の実行を一時停止し,次の命令のアドレスを被変調関数から戻ってから実行を継続するエントリポイントとして保存し,現場を保存する.そして、被変調関数のエントリアドレスに移動して被変調関数を実行する.return文または被変調関数が終了した後、以前に保存したフィールドを復元し、以前に保存した戻りアドレスからプライマリ変調関数の残りの部分を実行し続けます.
インライン関数呼び出しは、関数呼び出し後に続行するためにフィールド保護が必要です.関数が呼び出されると、実行を続行するにはフィールドを復元する必要があります.これはすべてシステムのオーバーヘッドが必要で、プログラムの効率に影響します.
インライン関数はコンパイル時に呼び出された関数コードを直接プライマリコール関数に埋め込み、定義方式は通常の関数定義の前にinlineを付け、プログラムフローのジャンプと戻りは存在しないが、プログラムコードを追加した.インライン関数関数体には複雑な構造制御文を含めることはできません.1~5行の小さな関数に適しています.関数の規模が比較的大きい場合,関数の実行時間は関数の呼び出しと戻り時間に比べてずっと大きく,時間と空間を総合して考えると,インラインではあまり意味がない.
原理:コンパイラは、任意のインライン関数に対して、名前、パラメータタイプ、戻り値タイプを含む関数の宣言をシンボルテーブルに入れます.コンパイラがインライン関数にエラーが見つからない場合、その関数のコードもシンボルテーブルに格納されます.インライン関数を呼び出すと、コンパイラはまず呼び出しが正しいかどうかをチェックします(タイプセキュリティチェックを行うか、自動タイプ変換を行います.もちろん、すべての関数について同じです).正しい場合、インライン関数のコードは直接関数呼び出しを置き換え、関数呼び出しのオーバーヘッドを省くことができます.
インライン関数とマクロの違い1.インライン関数は実行時にデバッグできますが、マクロ定義はできません.
2.コンパイラは、インライン関数のパラメータタイプをセキュリティチェックまたは自動タイプ変換(通常の関数と同じ)しますが、マクロ定義はしません.
3.インライン関数はクラスのメンバー変数にアクセスでき、マクロ定義はできません.
4.クラスで同時に定義されたメンバー関数を宣言し、自動的にインライン関数に変換します.
C++言語の関数インラインメカニズムは、マクロコードの効率性とセキュリティを向上させ、クラスのデータメンバーを自由に操作できる.したがって、C++プログラムでは、すべてのマクロコードの代わりにインライン関数を使用する必要があります.
実行可能ファイルのcppファイルの1つの関数は1回しか定義できません.関数を1つに定義するとhファイルに2つのcppを含めると、この関数がそれぞれ2つのcppで定義されてエラーが発生します.しかしinline関数は複数のcppで複数回定義できるので,この問題を解決した.
size()の呼び出しでは、実はインラインです.ループでは、v.size()の値を変数で保存して、ループごとの呼び出しコストを削減できます.そこで検索して、ついでにまとめることにしました.
1、inlineの引き出し
以下のmin()関数を考慮する
このような小さな操作のために関数を定義する利点は、a.コードがmin()の呼び出しを含む場合、このようなコードを読み、条件オペレータのインスタンスを読むよりも意味が強いことを説明することである.
b.1つの局所化された実装を変更することは、1つのアプリケーションの300個の出現を変更するよりもずっと容易である.
c.意味は統一されており、テストごとに同じ方法で実現することが保証されている.
d.関数は再利用可能であり、他のアプリケーションのためにコードを書き換える必要はない.
ただし、min()を関数として書くには、直接計算条件オペレータよりも呼び出し関数が遅いという深刻な欠点があります.では、以上の利点と効率を両立させることはできませんか.C++が提供するソリューションはinline(インライン)関数である
2、inlineの原理:コード代替
プログラムコンパイル時に、コンパイラは、プログラムに現れるインライン関数の呼び出し式をインライン関数の関数体で置き換えます.
例えば、1つの関数がinline関数として指定されている場合、プログラム内の各呼び出し点において、例えば、
コンパイル時に展開
min()を関数として書く余分な実行オーバーヘッドが解消される.3、inlineの使用
1つの関数をインライン関数にし、暗黙的にクラスで関数を定義し、明示的には関数の前にinlineキーワードの説明を加えます.
4、inlineの使用上の注意事項
a.inlineの原理から、inlineの原理は、空間で時間を交換する方法であり、コード膨張(複製)を代価とし、関数呼び出しのオーバーヘッドを省くだけで、関数の実行効率を高めることが明らかになった.関数内のコードを実行する時間が,関数呼び出しのオーバーヘッドよりも大きい場合,効率の収穫は少ない.したがって、関数体コードが長すぎる場合、または関数体重に循環文がある場合、if文またはswitch文または再帰の場合、インラインは使用しないでください.
b.キーワードinlineは、関数をインライン化するには、関数定義体と一緒に置く必要があります.inlineを関数宣言の前に置くだけでは何の役にも立たない.インライン関数を呼び出す前に宣言する必要があります.
以上のコードはインライン関数にはなりませんが、以下のようにできます.
したがって、inlineは「宣言用キーワード」ではなく「実装用キーワード」である.以上の例について、林鋭はまた、宣言と定義の前に加えるのではなく、定義の前にinlineを加えることを提案した.これは高品質のC++/Cプログラム設計スタイルの基本原則を体現することができるからだ.宣言と定義は混同してはいけない.c.inlineはコンパイラにとってただの提案であり、コンパイラはこの提案を無視することを選択することができる.言い換えれば、本当にinlineと書いても間違いがない場合、コンパイラは自動的に最適化されます.したがって、inlineに再帰、ループ、またはコードが多すぎると、コンパイラはinline宣言を自動的に無視し、同様に通常の関数として呼び出されます.
まとめ:
インラインはC++における関数固有のマクロとして理解でき,Cの関数マクロに対する改良であると考えられる.定数マクロの場合、C++はconstの代替を提供します.関数マクロの場合、C++が提供するスキームはinlineです.Cでは、マクロの利点はよく知られていますが、コンパイラはマクロコードをコピーすることで、パラメータスタックを省き、アセンブリのcall呼び出しを生成し、パラメータを返すなどの操作を行い、いくつかのセキュリティ上の危険性がありますが、効率的には、非常に望ましいです.しかし、関数マクロには多くの欠陥があります.主に以下のようなものがあります.
a.古典的な
実行文:
の場合、
b.マクロを使用して、デバッグすることができなくて、windowsはASSERTマクロc.を提供して、マクロを使用して、クラスのプライベートメンバーにアクセスすることができなくて、だから、C++はインラインメカニズムを通じて、マクロコードの効率を備えて、また安全性を増加して、また自由にクラスのデータメンバーを操作することができて、1つの比較的に完璧な解決策です.
インライン関数呼び出しは、関数呼び出し後に続行するためにフィールド保護が必要です.関数が呼び出されると、実行を続行するにはフィールドを復元する必要があります.これはすべてシステムのオーバーヘッドが必要で、プログラムの効率に影響します.
インライン関数はコンパイル時に呼び出された関数コードを直接プライマリコール関数に埋め込み、定義方式は通常の関数定義の前にinlineを付け、プログラムフローのジャンプと戻りは存在しないが、プログラムコードを追加した.インライン関数関数体には複雑な構造制御文を含めることはできません.1~5行の小さな関数に適しています.関数の規模が比較的大きい場合,関数の実行時間は関数の呼び出しと戻り時間に比べてずっと大きく,時間と空間を総合して考えると,インラインではあまり意味がない.
原理:コンパイラは、任意のインライン関数に対して、名前、パラメータタイプ、戻り値タイプを含む関数の宣言をシンボルテーブルに入れます.コンパイラがインライン関数にエラーが見つからない場合、その関数のコードもシンボルテーブルに格納されます.インライン関数を呼び出すと、コンパイラはまず呼び出しが正しいかどうかをチェックします(タイプセキュリティチェックを行うか、自動タイプ変換を行います.もちろん、すべての関数について同じです).正しい場合、インライン関数のコードは直接関数呼び出しを置き換え、関数呼び出しのオーバーヘッドを省くことができます.
インライン関数とマクロの違い1.インライン関数は実行時にデバッグできますが、マクロ定義はできません.
2.コンパイラは、インライン関数のパラメータタイプをセキュリティチェックまたは自動タイプ変換(通常の関数と同じ)しますが、マクロ定義はしません.
3.インライン関数はクラスのメンバー変数にアクセスでき、マクロ定義はできません.
4.クラスで同時に定義されたメンバー関数を宣言し、自動的にインライン関数に変換します.
C++言語の関数インラインメカニズムは、マクロコードの効率性とセキュリティを向上させ、クラスのデータメンバーを自由に操作できる.したがって、C++プログラムでは、すべてのマクロコードの代わりにインライン関数を使用する必要があります.
実行可能ファイルのcppファイルの1つの関数は1回しか定義できません.関数を1つに定義するとhファイルに2つのcppを含めると、この関数がそれぞれ2つのcppで定義されてエラーが発生します.しかしinline関数は複数のcppで複数回定義できるので,この問題を解決した.
for (int i=v.begin() ; i
size()の呼び出しでは、実はインラインです.ループでは、v.size()の値を変数で保存して、ループごとの呼び出しコストを削減できます.そこで検索して、ついでにまとめることにしました.
1、inlineの引き出し
以下のmin()関数を考慮する
int min( int v1, int v2 )
{
return( v1 < v2 << v1 : v2 );
}
このような小さな操作のために関数を定義する利点は、a.コードがmin()の呼び出しを含む場合、このようなコードを読み、条件オペレータのインスタンスを読むよりも意味が強いことを説明することである.
b.1つの局所化された実装を変更することは、1つのアプリケーションの300個の出現を変更するよりもずっと容易である.
c.意味は統一されており、テストごとに同じ方法で実現することが保証されている.
d.関数は再利用可能であり、他のアプリケーションのためにコードを書き換える必要はない.
ただし、min()を関数として書くには、直接計算条件オペレータよりも呼び出し関数が遅いという深刻な欠点があります.では、以上の利点と効率を両立させることはできませんか.C++が提供するソリューションはinline(インライン)関数である
2、inlineの原理:コード代替
プログラムコンパイル時に、コンパイラは、プログラムに現れるインライン関数の呼び出し式をインライン関数の関数体で置き換えます.
例えば、1つの関数がinline関数として指定されている場合、プログラム内の各呼び出し点において、例えば、
int minVal2 = min( i, j );
コンパイル時に展開
int minVal2 = i < j << i : j;
min()を関数として書く余分な実行オーバーヘッドが解消される.3、inlineの使用
1つの関数をインライン関数にし、暗黙的にクラスで関数を定義し、明示的には関数の前にinlineキーワードの説明を加えます.
4、inlineの使用上の注意事項
a.inlineの原理から、inlineの原理は、空間で時間を交換する方法であり、コード膨張(複製)を代価とし、関数呼び出しのオーバーヘッドを省くだけで、関数の実行効率を高めることが明らかになった.関数内のコードを実行する時間が,関数呼び出しのオーバーヘッドよりも大きい場合,効率の収穫は少ない.したがって、関数体コードが長すぎる場合、または関数体重に循環文がある場合、if文またはswitch文または再帰の場合、インラインは使用しないでください.
b.キーワードinlineは、関数をインライン化するには、関数定義体と一緒に置く必要があります.inlineを関数宣言の前に置くだけでは何の役にも立たない.インライン関数を呼び出す前に宣言する必要があります.
inline void Foo(int x, int y); // inline
void Foo(int x, int y)
{
...
}
以上のコードはインライン関数にはなりませんが、以下のようにできます.
void Foo(int x, int y);
inline void Foo(int x, int y) // inline
{
...
}
したがって、inlineは「宣言用キーワード」ではなく「実装用キーワード」である.以上の例について、林鋭はまた、宣言と定義の前に加えるのではなく、定義の前にinlineを加えることを提案した.これは高品質のC++/Cプログラム設計スタイルの基本原則を体現することができるからだ.宣言と定義は混同してはいけない.c.inlineはコンパイラにとってただの提案であり、コンパイラはこの提案を無視することを選択することができる.言い換えれば、本当にinlineと書いても間違いがない場合、コンパイラは自動的に最適化されます.したがって、inlineに再帰、ループ、またはコードが多すぎると、コンパイラはinline宣言を自動的に無視し、同様に通常の関数として呼び出されます.
まとめ:
インラインはC++における関数固有のマクロとして理解でき,Cの関数マクロに対する改良であると考えられる.定数マクロの場合、C++はconstの代替を提供します.関数マクロの場合、C++が提供するスキームはinlineです.Cでは、マクロの利点はよく知られていますが、コンパイラはマクロコードをコピーすることで、パラメータスタックを省き、アセンブリのcall呼び出しを生成し、パラメータを返すなどの操作を行い、いくつかのセキュリティ上の危険性がありますが、効率的には、非常に望ましいです.しかし、関数マクロには多くの欠陥があります.主に以下のようなものがあります.
a.古典的な
#define MAX(a, b) (a) > (b) ? (a) : (b)
実行文:
result = MAX(i, j) + 2 ;
の場合、
result = (i) > (j) ? (i) : (j) + 2 ;
b.マクロを使用して、デバッグすることができなくて、windowsはASSERTマクロc.を提供して、マクロを使用して、クラスのプライベートメンバーにアクセスすることができなくて、だから、C++はインラインメカニズムを通じて、マクロコードの効率を備えて、また安全性を増加して、また自由にクラスのデータメンバーを操作することができて、1つの比較的に完璧な解決策です.