• このエントリーをはてなブックマークに追加

スポンサードリンク

はじめに

C/C++ における イベントハンドラの書き方について,定石を整理してみた.

前提

以下のようなコードがあるとする.

#include <iostream>
typedef enum {START,  STOP} COMMAND;

void check (COMMAND command) {
  std::cout << (int) command << " is called" << std::endl;
}

int main (int argc, char *argv&#91;&#93;)
{
  check (START);
  check (STOP);
  return 0;
}
&#91;/sourcecode&#93;

<p> 出力結果は以下のようになる. </p>


0 is called
1 is called

この出力結果は以下のようにしたい.

start is called
stop is called

方法

switch を使う

一番単純な方法は, switch をつかって, 表示を分岐する

void onStart () { std::cout << "start is called" << std::endl; } void onStop () { std::cout << "stop is called" << std::endl; } void check (COMMAND command) { switch (command) { case START: onStart (); break; case STOP: onStop (); break; } } }; [/sourcecode]

関数ポインタ配列を使う

別の定石は, 関数ポインタ配列をつかう.

#include

typedef enum {START, STOP} COMMAND;

void onStart () { std::cout << "start is called" << std::endl; } void onStop () { std::cout << "stop is called" << std::endl; } typedef void (*HANDLER) (); static HANDLER handle_tbl[2] = {&onStart, &onStop}; void check (COMMAND command) { handle_tbl[command] (); } [/sourcecode]

lambda をつかう

関数テーブルに関数を登録するために, 関数を作成する必要があるけれども, 一行なので, 関数を作成するのは面倒.

そんなときは,c++11 からつかえるようになったラムダ式を利用する.

#include
#include

typedef enum {START, STOP} COMMAND;

static std::function handle_tbl[2] = {
[] (){ std::cout << "start is called" << std::endl;}, [] (){ std::cout << "stop is called" << std::endl;} }; void check (COMMAND command) { handle_tbl[command] (); } int main (int argc, char *argv[]) { check (START); check (STOP); return 0; } [/sourcecode]

やっぱり, これからは関数型の時代だよね!