はじめに
C# から C++ に移行した際、C# の Delegate
が C++ には存在しないことを知り、
自作で Delegate
を実装してみました。
C++ 初心者なので間違いがあればごめんなさい。
実装内容
以下が実際に作った Delegate
クラスのコードです。
Delegate.h
#pragma once
#include <vector>
#include <functional>
class Delegate
{
public:
// 関数を登録
void Add(std::function<void()> func);
// 関数を削除
void Remove(std::function<void()> funcToRemove);
// 登録した関数をすべて呼び出し
void Invoke();
// 登録した関数をすべて削除
void Clear();
private:
std::vector<std::function<void()>> delegates;
};
Delegate.cpp
#include "Delegate.h"
#include <algorithm>
// 関数を登録
void Delegate::Add(std::function<void()> func)
{
delegates.push_back(func);
}
// 関数を削除
void Delegate::Remove(std::function<void()> funcToRemove)
{
auto it = std::find_if(delegates.begin(), delegates.end(),
[&funcToRemove](const std::function<void()>& func)
{
return func.target<void()>() == funcToRemove.target<void()>();
});
if (it != delegates.end())
{
delegates.erase(it);
}
}
// 登録した関数を呼び出し
void Delegate::Invoke()
{
for (auto& delegate : delegates)
{
delegate();
}
}
// 登録した関数をすべて削除
void Delegate::Clear()
{
delegates.clear();
}
使い方
以下は、Delegate
クラスを使った具体的な例です。
#include "Delegate.h"
#include <iostream>
void Log()
{
std::cout << "ハロー!\n";
}
int main()
{
Delegate* delegate = new Delegate();
// 関数を登録
delegate->Add(Log);
// 登録した関数をすべて実行
delegate->Invoke();
// 後処理(メモリ解放)
delete delegate;
return 0;
}
実行結果
ハロー!
解説
C++ の std::function
と std::vector
を使い、複数の関数を動的に登録・削除・実行する仕組みを実現しました。
-
Add
新しい関数をリストに追加します。 -
Remove
登録した関数を削除します。関数ポインタを比較するために、std::function::target
を使っています。 -
Invoke
登録した関数をすべて呼び出します。 -
Clear
全登録を削除してリセットします。
まとめ
C# の Delegate
に近い動作を C++ で実現できるようになりました!
この仕組みを活用して、Unity の Input System のようなシステムを作れたらと思います。
C++ でもう少し簡潔に書ける方法や改善点があればぜひ教えてください!