メンバ関数ポインタへの代入

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
YYSS
記事: 125
登録日時: 9年前
連絡を取る:

メンバ関数ポインタへの代入

#1

投稿記事 by YYSS » 9年前

最近、関数ポインタを学び始めた者です。

関数ポインタが色々と便利なものだと言うことを知り、
ソースコードの一部に使用してみようと思ったのですが、代入が上手くいきません;;

コード:

class C_LaserObj{

public:
	//関数ポインタ
	void (*LaserAct)();

	void HormingLaserAct();

};

class C_Laser{

private:
       //コンポジッション
	C_LaserObj Laser[ 1024 ];
public:
	C_Laser();
        void MoveSet( int num );

}

コード:

void C_Laser:: MoveSet( int num ){

	Laser[num].LaserAct		= &C_LaserObj::HormingLaserAct;
}
という風に、C_LaserObjのメンバ関数ポインタに関数のアドレスを入れたいのですが、
「error C2440: '=' : 'void (__thiscall C_LaserObj::* )(void)' から 'void (__cdecl *)(void)' に変換できません。」
というエラーが出て思うように行きません;

どこが違っているのか指摘してくださると幸いです。

~開発環境~
○Windows 7 Ultimate SP1
○Visual C++ 2010 Express
○DXライブラリ使用

アバター
a5ua
記事: 199
登録日時: 10年前

Re: メンバ関数ポインタへの代入

#2

投稿記事 by a5ua » 9年前

メンバ関数へのポインタは以下のように宣言します。

コード:

class C_LaserObj
{
public:
    /* メンバ関数へのポインタ */
    void (C_LaserObj::*LaserAct)();

    void HormingLaserAct();
};

アバター
GRAM
記事: 164
登録日時: 10年前
住所: 大阪

Re: メンバ関数ポインタへの代入

#3

投稿記事 by GRAM » 9年前

非staticなメンバ関数と、非メンバ関数及びstaticなメンバ関数は関数ポインタの使い方が少し違います。

これは非staticなメンバ関数ではその関数内でthisポインタを使えるためです。
具体的な解決策はa5uaさんが示した通りですし、もしくはHormingLaserActの前にstaticを付けて
static void HormingLaserAct();とすればコンパイルは通ります。
(この場合コードを見ただけではどういう解決策が適切かよくわかりませんでしたので一応)

アバター
YYSS
記事: 125
登録日時: 9年前
連絡を取る:

Re: メンバ関数ポインタへの代入

#4

投稿記事 by YYSS » 9年前

回答ありがとうございます。

コード:

class C_LaserObj
{
public:
    /* メンバ関数へのポインタ */
    void (C_LaserObj::*LaserAct)();
 
    void HormingLaserAct();
};
のやり方でやったら無事に代入は出来ました。
thisポインタについては、はじめて聞く言葉なので後で調べておきたいと思います。



で、代入は出来たのですが、次はその関数ポインタを呼ぼうとするとエラーが出てしまいます;;

コード:

	//呼ぶとき
	(Laser[i].*LaserAct)();
「error C2065: 'LaserAct' : 定義されていない識別子です。」


定義はちゃんとしていると思うのですが、何故エラーが出るのかが分かりません

コード:

class C_LaserObj{
 
public:
    double x, y, angle, speed;
    //関数ポインタ
    void (C_LaserObj::*LaserAct)();
     void HormingLaserAct();
 
};
 
class C_Laser{
 
private:
       //コンポジッション
    C_LaserObj Laser[ 1024 ];
public:
    C_Laser();
        void MoveSet( int num );
        void LaserMain( int num );
 
}

void C_Laser:: MoveSet( int num ){
 
    Laser[num].LaserAct     = &C_LaserObj::HormingLaserAct;
}

void C_Laser:: LaserMain( int num ){
 
    (Laser[num].*LaserAct)();
}
HormingLaserActはメンバ変数を操作するので、静的メンバ関数にはできません
完全に迷宮入りした状態なので、手助けをしてくださると嬉しいです。

よしぴー

Re: メンバ関数ポインタへの代入

#5

投稿記事 by よしぴー » 9年前

コード:

      (Laser[num].*Laser[num].LaserAct)();
と記述すればOKです。

アバター
a5ua
記事: 199
登録日時: 10年前

Re: メンバ関数ポインタへの代入

#6

投稿記事 by a5ua » 9年前

個人的には、関数ポインタを経由してメンバ関数を呼び出す処理を、C_LaserObjに書いたほうがわかりやすいと思います。

コード:

#include <iostream>

class C_LaserObj {
	double x, y, angle, speed;
	void (C_LaserObj::*LaserAct)();
public:
	void SetAction(void (C_LaserObj::*action)()) {
		LaserAct = action;
	}

	void DoAction() {
		(this->*LaserAct)();
	}
	
	void HormingLaserAct() {
		std::cout << "HormingLaserAct()" << std::endl;
	}
};

class C_Laser {
	C_LaserObj Laser[ 1024 ];
public:
	void MoveSet( int num ) {
		Laser[num].SetAction(&C_LaserObj::HormingLaserAct);
	}
	void LaserMain( int num ) {
		Laser[num].DoAction();
	}
};

int main() {
	C_Laser x;
	x.MoveSet(0);
	x.LaserMain(0);
}

アバター
YYSS
記事: 125
登録日時: 9年前
連絡を取る:

Re: メンバ関数ポインタへの代入

#7

投稿記事 by YYSS » 9年前

回答ありがとうございます。

無事に関数ポインタを実装することが出来、スマートなソースコード?になりました。

また何かあったらよろしくお願いします!

閉鎖

“C言語何でも質問掲示板” へ戻る