9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

メンバー関数ポインタと配列を使って、メンバー関数を番号で指定して呼び出す方法

Posted at

備忘録ですが、せっかく記事にするので体裁を整えて記述したいと思います。
#はじめに(事例)#
公開クラスの関数に、番号を指定することで挙動を変えたいのですが、どのように書けばよいのでしょうか?
#コード#


#include <iostream>
#include <memory>

// 実務クラスのプライベートメンバー関数を番号で指定して呼び出したい。
// 参考書の通りに書くと、プライベート非staticメンバー関数・・・

using ub4 = unsigned int;

// 外部に公開して利用するクラス
class A {
public: // クラスの外で using を使いたいので public にしている。
    class impl; // 実務クラスの宣言
private:
    std::unique_ptr<impl> pim;
public:
    A();
    ~A();
public:
    void func_call( ub4 fn_num );
};

// メンバー関数ポインタへの型を宣言
using a_fn_ptr_t = void ( A::impl:: * )();

// 実務クラス
class A::impl {
    static constexpr ub4 pf_num = 4; // 定数で配列の要素数を指定
    static a_fn_ptr_t func_ar[ pf_num ];
public:
    impl();
    ~impl();
public:
    void func_call( ub4 fn_num );
private:
    void func_00();
    void func_01();
    void func_02();
    void func_03();
};

// 配列にメンバー関数ポインタを入れる
a_fn_ptr_t A::impl::func_ar[] = {
    &A::impl::func_00,
    &A::impl::func_01,
    &A::impl::func_02,
    &A::impl::func_03
};

A::A() :
    pim ( new impl() )
{}

A::~A()
{}

void A::func_call( ub4 fn_num )
{
    pim->func_call( fn_num );
}

A::impl::impl()  { printf("A::impl::impl() \n");}
A::impl::~impl() { printf("A::impl::~impl()\n");}


void A::impl::func_call( ub4 fn_num )
{
    if( fn_num >= pf_num ) return; // 申し訳程度のチェック
    ( this->*( func_ar[ fn_num ] ) )(); // 配列に入っているメンバー関数を呼び出し。
}

// 何らかの実務関数
void A::impl::func_00() { printf("A::impl::func_00()\n"); }
void A::impl::func_01() { printf("A::impl::func_01()\n"); }
void A::impl::func_02() { printf("A::impl::func_02()\n"); }
void A::impl::func_03() { printf("A::impl::func_03()\n"); }


// 実際に使えるかテストしてみる。
int main()
{
    A a;
    a.func_call( 0 );
    a.func_call( 1 );
    a.func_call( 2 );
    a.func_call( 3 );
    a.func_call( 4 );
    a.func_call( 5 );
    a.func_call( 6 );

    return 0;
}

##結果##



Start

A::impl::impl() 
A::impl::func_00()
A::impl::func_01()
A::impl::func_02()
A::impl::func_03()
A::impl::~impl()

0

Finish

#参照#

Wandboxにて確認させて頂きました。
http://melpon.org/wandbox/permlink/bqi7Pu16WuetcmJ9

C++11参考書:関数呼び出し(Function call)
http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#expr.call

C++11参考書:メンバーへのポインター演算子(Pointer-to-member operators)
http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#expr.mptr.oper

C++11参考書:非staticメンバー関数(Nonstatic member functions)
http://ezoeryou.github.io/cpp-book/C++11-Syntax-and-Feature.xhtml#class.mfct.non-static

#その他#
コードの色付けが無いとさっぱり分からないです。
ちなみに私の環境
windows7 64bit
Microsoft Visual Studio Express 2013 for Windows Desktop
では、以下のように表示させています。

sample_code.jpg.jpg

色が赤くなるほどなんかヤバイ感じ、気を付けなきゃいけない感じが出るようにしているのですが、これはそのうち別記事に書こうかなと思います。

あと
非staticメンバー関数  という記述の仕方は最初とまどいますね。
一般人の私にとっては  普通のメンバー関数 と記述したいところです。

以上です。

何か指摘事項がございましたら、お気軽にコメントお願いしまーす。

9
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?