関数ポインタ | Programming Place Plus 用語集

トップページ用語集

名称 🔗

解説 🔗

プログラミングにおけるポインタの一種で、関数を指し示すものです。

多くの場合、実体としては「どの関数を呼び出すか」を表すメモリアドレスなど)を保持することによって、ある1つの関数を指し示します。指し示している関数がないことを示すためにヌルポインタを用いることができます。また、関数には仮引数戻り値があるため、関数ポインタもそれらのを含むことが一般的です。

関数ポインタを間接参照することにより、指し示す先にある関数を呼び出すことができます。

保持している値を変更することによって、呼び出す関数をあとから差し替えることができます。これにより、条件に応じて処理を切り替えたり、共通処理に利用者側の処理を渡したりする(コールバック)ことを実現しやすくなります。

関数を指し示している関数ポインタに対して、オブジェクトを指し示しているポインタをオブジェクトポインタと呼ぶことがあります。

C言語の場合 🔗

C言語の関数ポインタは、関数の仮引数や戻り値の型を含むように宣言します。

int f(const char* str);  // 関数の宣言

int (*fp1)(const char*) = f;  // 関数ポインタの宣言と初期化
int (*fp2)(const char*) = &f; // 同上

関数ポインタを間接参照することにより、指し示す先にある関数を呼び出せます。オブジェクトポインタと同様、* を用いて間接参照しますが、関数ポインタの場合はより簡単に、通常の関数であるかのように呼び出すこともできます。

int ret1 = (*fp1)("hello");  // 関数ポインタを間接参照して関数を呼び出す

int ret2 = fp2("hello");  // より簡単な呼び出し方

C言語の関数ポインタに関する詳細な解説は、C言語編「ポインタ⑧(関数ポインタ)」のページにあります。

C++ の場合 🔗

C++ の関数ポインタはC言語のものと同様です。名前空間内にあるフリー関数や、静的メンバ関数を関数ポインタで指し示すことも可能です。

namespace N {
    int f(const char* str);  // 関数の宣言
}

struct S {
    static int f(const char* str);  // 静的メンバ関数の宣言
};

int (*fp1)(const char*) = N::f;
int (*fp2)(const char*) = S::f;

例外的なのは静的でないメンバ関数で、これは対象のオブジェクトの存在が必要であり、メンバポインタ(メンバ関数ポインタ)の仕組みを用いる必要があります。

struct S {
    int f(const char* str);  // 静的でないメンバ関数の宣言
};

int (S::*fp)(const char*) = &S::f;  // メンバポインタの宣言と初期化
S s {};
int ret = (s.*fp)("hello");  // メンバポインタを間接参照して関数を呼び出す

C++ では、関数オブジェクトラムダ式を用いることで、関数ポインタのような振る舞いが実現できます。

C++ の関数オブジェクトは、operator()定義したクラスの実体です。関数オブジェクト自体は関数でも関数ポインタでもありませんが、関数であるかのように呼び出すことができます。C++ のラムダ式は、関数オブジェクトを簡潔に記述する構文です。

関数オブジェクトは、関数ポインタと異なり、データメンバによって状態を保持できることが特徴的です。

// 関数オブジェクト
struct FuncObj {
    int operator()(const char* str) const {
        return 123;
    }
};

FuncObj fo {};
int ret1 {fo("hello")};

// ラムダ式
auto lambda = [](const char* str) -> int {
    return 123;
};
int ret2 {lambda("hello")};

C++ の関数ポインタ、関数オブジェクト、ラムダ式に関する詳細な解説は、新C++編「関数ポインタとラムダ式」メンバ関数ポインタについては「クラス」のページにあります。


参考リンク 🔗

更新履歴 🔗


用語集のトップページへ

Programming Place Plus のトップページへ



はてなブックマーク に保存 Facebook でシェア X で ポストフォロー
LINE で送る noteで書く rss1.0 取得ボタン RSS
管理者情報 プライバシーポリシー
先頭へ戻る