ささみのメモ帳

ゲーム会社で働く、無能プログラマーが自分のためのメモ帳として利用しています。

C/C++で基本的な関数ポインタの使い方メモ

関数ポインタとは

関数を指すためのポインタ(メモリアドレス)のことで、 C、C++C#などでは一般的に使用されます。

以下は、プログラム初心者に向きの簡単なC++での関数ポインタの利用例です。

一般的なやつ

#include <stdio.h>

// 戻り値なし、引数 int の関数ポインタの定義
typedef void (*FuncPointer)(int);

void FuncA(int x) {
    std::cout << "Function A: " << x << std::endl;
}

void FuncB(int x) {
    std::cout << "Function B: " << x << std::endl;
}

int main() {
    // 関数ポインタの宣言
    FuncPointer funcPtr;

    funcPtr = FuncA;
    funcPtr (10); // Function A: 10

    funcPtr = FuncB;
    funcPtr (20);  // Function B: 20

    return 0;
}

クラス指定するやつ

#include <stdio.h>

class ClassA
{
public:
    void Func(int x) {
        std::cout << "Class A: " << x << std::endl;
    }
};

class ClassB
{
public:
    void Func(int x) {
        std::cout << "Class B: " << x << std::endl;
    }
};

// ClassAの戻り値なし、引数 int の関数ポインタの定義
typedef void (ClassA::* FuncPointer)(int);

int main() {
    // 関数ポインタの宣言
    FuncPointer funcPtr;
    ClassA classA;

    funcPtr = &ClassA::Func;
    (classA.*funcPtr)(10); // Class A: 10

    funcPtr = &ClassB::Func;// Classが一致しないのでエラー

    return 0;
}

Pairにして配列にしてつかうやつ

bool BoolFuncA() { return true; }
bool BoolFuncB() { return false; }
void FuncA(int x) { std::cout << "Function A: " << x << std::endl; }
void FuncB(int x) { std::cout << "Function B: " << x << std::endl; }

int main() {
    // 関数ポインタペアの配列定義
    std::pair< bool (*)(void), void (*)(int)> funcPairs[] = {
        { &BoolFuncA, &FuncA },
        { &BoolFuncB, &FuncB }
    };
    // 配列を回して中身を実行
    for (auto funcPair : funcPairs)
    {
        if (funcPair.first())
        {
            funcPair.second(10);
        }
    }

    return 0;
}

ラムダ式Pairにして配列にしてつかうやつ

#include <functional>

bool BoolFuncA() { return true; }
bool BoolFuncB() { return false; }
bool BoolFuncC() { return true; }

void FuncC(int x) { std::cout << "Function C: " << x << std::endl; }

int main() {
    // ラムダ式を含めた関数ポインタペアの配列定義
    std::pair< bool(*)(void), std::function<void(int)>> funcPairs[] = {
        { &BoolFuncA, [](int x) { std::cout << "Function A: " << x << std::endl; }},
        { &BoolFuncB, [](int x) { std::cout << "Function B: " << x << std::endl; }},
        { &BoolFuncC, &FuncC }
    };

    for (auto funcPair : funcPairs)
    {
        if (funcPair.first())
        {
            funcPair.second(10);
        }
    }

    return 0;
}