インライン関数
クラス:インデックス への移動
メンバ関数は、クラス内で宣言し他の場所で定義することができます。あるいは、クラス内でメンバ関数の宣言と定義を両方とも行うこともでき、その場合、メンバ関数はインライン関数と呼ばれます。
コンパイラは、関数呼び出しを関数本体のコンパイル済みコードに直接置き換えることにより、通常の関数呼び出しのオーバーヘッドを減らすことができる場合があります。このプロセスは、関数本体のインライン展開と呼ばれますが、関数名や引数のスコープには影響を与えません。インライン展開は、常に可能なわけではありません。inline 指定子で、コンパイラにインライン展開を指示します。
明示的または暗黙的な inline 要求は、オーバーロードされた演算子を実装する演算子関数などの、頻繁に使用される小さい関数に用いるのが一番よいでしょう。たとえば、次のような func のクラス宣言は、
int i; // グローバルな int
class X {
public:
char* func(void) { return i; } // デフォルトではインライン
char* i;
};
次の宣言と同等です。
inline char* X::func(void) { return i; }
func は、inline 指定子を明示して、クラスの外部で定義されています。func から返される値 i は、クラス X の char* i
です(「メンバのスコープ」を参照)。
インライン関数と例外
例外指定を伴うインライン関数はコンパイラでインライン展開されません。次に例を示します。
inline void f1() throw(int)
{
// 警告:例外指定を伴う関数はインライン展開されない
}
以下に示す制限事項は、デストラクタによるクリーンアップが有効な場合にのみ適用されます。
"デストラクタを持つクラス" 型のパラメータを 1 つでも取るインライン関数は、インライン展開されません。この制限は、参照で渡されるクラスには適用されないことに注意してください。
例:
struct foo {
foo();
~foo();
};
inline void f2(foo& x)
{
// 警告なし。f2() はインライン展開可能
}
inline void f3(foo x)
{
// 警告:値渡しのクラス型引数を取る関数は
// インライン展開されない
}
デストラクタを持つクラスを値で返すインライン関数は、破棄する必要がある変数や一時オブジェクトが return 式の中にある場合は常にインライン展開されません。
struct foo {
foo();
~foo();
};
inline foo f4()
{
return foo();
// 警告なし。f4() はインライン展開可能
}
inline foo f5()
{
foo X;
return foo(); // オブジェクト X は破棄する必要がある
// 警告:上記のような return 文が含まれている関数は
// インライン展開されない
}
inline foo f6()
{
return ( foo(), foo() ); // 戻り値に一時オブジェクトが含まれている
// 警告:上記のような return 文が含まれている関数は
// インライン展開されない
}