ページ 11

メンバ関数ポインタを用いたアクセスについて

Posted: 2016年11月04日(金) 21:10
by マック
メンバ関数へのポインタについて勉強しています。

以下のコードを若干修正し、
http://dixq.net/forum/viewtopic.php?f=3&t=3644#p30417

以下のコードを書きました。(コード欄を参照)

o 変更点
- Func fc[7] をTest classのメンバから、グローバル変数へと修正。
- FuncA-FuncGをpublicに変更。

o 問題
以下のコンパイルエラーが発生します。
-----------------------------------------------------------------------------------
func_ptr5.cpp:89:8: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘fc[0] (...)’, e.g. ‘(... ->* fc[0]) (...)’
fc[0]();
^
-----------------------------------------------------------------------------------

o やりたいこと
classのpublic 関数へのポインタを、初期化時にclass外の変数にコピーし、
オブジェクト生成後、その変数を利用し、class外から関数にアクセスできるようにしたい。

o 疑問
class外から、これらの関数にどのようにアクセスすればよいかがわかりません。
もしご存知の方がいらっしゃったらご教授いただけないでしょうか?

o コード

コード:

#include <iostream>

using namespace std;

#include<stdio.h>

class Test;

typedef void(Test::*Func)();
Func fc[7];

class Test{
public:
	Test();
	~Test();
	void Top(void);
//private:

	void FuncA(void);
	void FuncB(void);
	void FuncC(void);
	void FuncD(void);
	void FuncE(void);
	void FuncF(void);
	void FuncG(void);
};

Test::Test()
{
	fc[0] = &Test::FuncA;
	fc[1] = &Test::FuncB;
	fc[2] = &Test::FuncC;
	fc[3] = &Test::FuncD;
	fc[4] = &Test::FuncE;
	fc[5] = &Test::FuncF;
	fc[6] = &Test::FuncG;
}

Test::~Test()
{

}

void Test::Top(void)
{
	/* for(int i = 0; i < 7; i++) */
	/* 	(this->*fc[i])(); */
}

void Test::FuncA(void)
{
	printf("お茶\n");
}

void Test::FuncB(void)
{
	printf("ほうじ茶\n");
}

void Test::FuncC(void)
{
	printf("はと麦茶\n");
}

void Test::FuncD(void)
{
	printf("プーアール茶\n");
}

void Test::FuncE(void)
{
	printf("シルベスタギムネマ茶\n");
}

void Test::FuncF(void)
{
	printf("梅こぶ茶\n");
}

void Test::FuncG(void)
{
	printf("玉露\n");
}

int main(void)
{
	Test test;
	//test.Top();
	fc[0]();


	return(0);
}

Re: メンバ関数ポインタを用いたアクセスについて

Posted: 2016年11月04日(金) 21:19
by あんどーなつ
ロベールのC++教室に答えが書いてあったと思います。

http://www7b.biglobe.ne.jp/~robe/cpphtm ... 03057.html

Re: メンバ関数ポインタを用いたアクセスについて

Posted: 2016年11月04日(金) 21:39
by マック
あんドーナツ様、

電光石火のご返信、感謝いたします。
以下の記述でアクセスできました。

コード:

 
int main(void)
{
	Test test;
	//test.Top();
	(test.*fc[0])();

	return(0);
}


ありがとうございました。

Re: メンバ関数ポインタを用いたアクセスについて

Posted: 2016年11月04日(金) 22:21
by あんどーなつ
2009年のトピックを見させていただきました。もしかして、こういうことをやりたいのかなとコードを書いてみました。
間違ってたらごめんなさい。

コード:

#include <iostream>
#include <string>

using namespace std;

class Tea {
	Tea *prev = nullptr;
	Tea *next = nullptr;
	string caption;
protected:
	Tea(const char *str, Tea *oldbro) {
		if (oldbro != nullptr)
			oldbro->next = this;
		prev = oldbro;
		caption = str;
	};
public:
	virtual ~Tea() {
		if (prev != nullptr) prev->~Tea();
	};
public:
	static Tea *Create();
	string GetCaption() { return caption; };
	Tea *GetPrevious() { return prev; };
	Tea *GetNext() { return next; };
};

class Houjicha : public Tea {
	public: Houjicha(Tea *b) : Tea("ほうじ茶", b) { }; };
class Hatomugicha : public Tea {
	public: Hatomugicha(Tea *b) : Tea("はとむぎ茶", b) { }; };
class PuErhTea : public Tea {
	public: PuErhTea(Tea *b) : Tea("プーアール茶", b) { }; };

Tea *Tea::Create() {
	return
	 new PuErhTea(
	  new Hatomugicha(
	   new Houjicha(nullptr)));
}

int main() {
	Tea *tea = Tea::Create();
	Tea *prev;
	while ((prev = tea->GetPrevious()) != nullptr)
		tea = prev;
	do {
		cout << (tea->GetCaption()) << endl;
	} while ((tea = tea->GetNext()) != nullptr);

	return 0;
}