C++におけるインライン関数と関数のリロードの詳細

4698 ワード

インライン関数
関数を呼び出すには、一定の時間と空間のオーバーヘッドが必要です.C++は、コンパイル時に関数呼び出しを関数体に置き換える効率を向上させる方法を提供し、C言語のマクロ展開と同様である.このような関数呼び出しに直接関数体を埋め込む関数をインライン関数(inline function)と呼び、インライン関数またはインライン関数とも呼ぶ.
インライン関数を指定する方法は簡単で、関数を定義するときにinlineキーを追加するだけです.
注:関数宣言時ではなく、関数定義時にinlineキーワードを追加します.関数宣言時にinlineキーを追加してもエラーはありませんが、効果はありません.
inlineキーワードは関数宣言では機能しません.

inline void swap(int &a, int &b);
void swap(int &a, int &b)
{
  int temp = a;
  a = b;
  b = temp;
}
inline              :
void swap(int &a, int &b);
inline void swap(int &a, int &b)
{
  int temp = a;
  a = b;
  b = temp;
}

インライン関数を使用すると、関数呼び出しのオーバーヘッドを効果的に回避でき、プログラムの実行効率が向上します.インライン関数を使用する欠点は、インライン関数として宣言された関数体が非常に大きい場合、コンパイラコンパイル後のプログラムの実行可能コードが大きくなることです.
また、関数内にループや他の複雑な制御構造が発生した場合、この場合、これらの複雑な制御構造を処理するのにかかる時間は、関数呼び出しにかかる時間よりもはるかに大きいため、このような関数をインライン関数として宣言することは意味がなく、コンパイル後に実行可能なコードが長くなる.
通常、プログラム設計の過程で、頻繁に呼び出される短い関数をインライン関数として宣言します.
説明:関数をinline宣言するのは、プログラマがコンパイルシステムに対して提案しただけです.つまり、命令的ではなく、提案的です.inlineとして指定されると、コンパイルシステムはそうしなければなりません.コンパイルシステムは、状況に応じてそうするかどうかを決定します.
完全な例:

#include 
using namespace std;
int max(int, int, int); //    ,      inline
int main( )
{
  int i=10, j=20, k=30, m;
  m = max(i, j, k);
  cout<a) a=b;
  if(c>a) a=c;
  return a;
}

実行結果:

max=30

関数を定義するときに組み込み関数として指定するため、コンパイルシステムは、関数呼び出し「max(i,j,k)」に遭遇すると、max関数体のコードを「max(i,j,k)」の代わりに使用し、同時に実パラメータをパラメータの代わりに使用する.このように、プログラム6行目「m=max(i,j,k);」次のように置き換えられます.

  if (j>i) i=j;
  if(k>i) i=k;
  m=i;

関数の再ロード
プログラミングでは、同じ機能を実現する場合がありますが、いくつかの詳細が異なります.例えば、3つの数の中から最大のものを見つけたいが、最大数を求めるたびにデータのタイプが異なり、3つの整数、3つの二重精度数、または3つの長い整数である可能性がある.プログラム設計者は往々にしてそれぞれ3つの同名でない関数を設計し、その関数の原型は以下の通りである.

  int max1(int a, int b, int c); // 3        
  double max2(double a, double b, double c); // 3         
  long max3(long a, long b, long c); // 3         

C++を使用すると、同じ関数名で複数の関数を定義できます.これらの関数のパラメータ数とパラメータタイプは異なります.これが関数のリロードです.すなわち、1つの関数名に新しい意味を再付与し、1つの関数名を多く使用できるようにする.
上記の最大数を求める問題については,以下のC++プログラムを記述することができる.
【例】3つの数の中で最大の数を求める(整数、二重精度数、長整数をそれぞれ考慮する場合).

#include 
using namespace std;
int main( )
{
  int max(int a,int b,int c); //    
  double max(double a,double b,double c); //    
  long max(long a,long b,long c);//    
  int i1,i2,i3,i;
  cin>>i1>>i2>>i3; //  3   
  i=max(i1,i2,i3); // 3        
  cout<>d1>>d2>>d3; //  3     
  d=max(d1,d2,d3); // 3          
  cout<>g1>>g2>>g3; //  3    
  g=max(g1,g2,g3); // 3         
  cout<a) a=b;
  if(c>a) a=c;
  return a;
}
double max(double a,double b,double c)//   3             
{
  if(b>a) a=b;
  if(c>a) a=c;
  return a;
}
long max(long a,long b,long c) //   3            
{
  if(b>a) a=b;
  if(c>a) a=c;
  return a;
}

次のように動作します.

185-76567�L (  3   )
56.87 90.23 -3214.78�L (  3   )
67854 -912456 673456�L (  3    )
i_max=567 (  3       )
d_max=90.23 (  3         )
g_max=673456 (  3        )

前例の3つのmax関数の関数体は同じである.
実際には、リロード関数は関数体が同じであることを要求しません.パラメータの種類の違いに加えて、パラメータの個数の違いも許可されます.
【例】2つの整数または3つの整数の最大数を求めるプログラムを作成する.2つの整数を入力すると、プログラムはこの2つの整数の最大数を出力し、3つの整数を入力すると、プログラムはこの3つの整数の最大数を出力します.

#include 
using namespace std;
int main( )
{
  int max(int a,int b,int c); //    
  int max(int a,int b); //    
  int a=8,b=-12,c=27;
  cout<a) a=b;
  if(c>a) a=c;
  return a;
}
int max(int a,int b)// max                
{
  if(a>b) return a;
  else return b;
}

次のように動作します.

max(a, b, c)=27
max(a, b)=8

max関数を2回呼び出すパラメータの個数が異なる場合、システムはパラメータの個数に基づいて一致する関数を見つけて呼び出す.
パラメータの個数とタイプは異なります.ただし、関数のタイプのみが異なり、パラメータの個数とタイプが同じではありません.例:

  int f(int); //        
  long f(int); //         
  void f(int); //      

関数呼び出し時には「f(10)」のように同じ形式である.コンパイルシステムでは、どの関数を呼び出すべきか判別できません.リロード関数のパラメータ個数、パラメータタイプ、またはパラメータ順序の3つのうち少なくとも1つが異なる必要があり、関数戻り値タイプは同じでも異なってもよい.
リロード関数を使用する場合、同名関数の機能は同じか近いべきで、同じ関数名で全く関係のない機能を実現しないでください.プログラムも実行できますが、可読性が悪くて、わけがわかりません.