ページ 1 / 1
メンバ関数ポインタへの代入
Posted: 2011年8月20日(土) 00:57
by YYSS
最近、関数ポインタを学び始めた者です。
関数ポインタが色々と便利なものだと言うことを知り、
ソースコードの一部に使用してみようと思ったのですが、代入が上手くいきません;;
コード:
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ライブラリ使用
Re: メンバ関数ポインタへの代入
Posted: 2011年8月20日(土) 01:48
by a5ua
メンバ関数へのポインタは以下のように宣言します。
コード:
class C_LaserObj
{
public:
/* メンバ関数へのポインタ */
void (C_LaserObj::*LaserAct)();
void HormingLaserAct();
};
Re: メンバ関数ポインタへの代入
Posted: 2011年8月20日(土) 02:00
by GRAM
非staticなメンバ関数と、非メンバ関数及びstaticなメンバ関数は関数ポインタの使い方が少し違います。
これは非staticなメンバ関数ではその関数内でthisポインタを使えるためです。
具体的な解決策はa5uaさんが示した通りですし、もしくはHormingLaserActの前にstaticを付けて
static void HormingLaserAct();とすればコンパイルは通ります。
(この場合コードを見ただけではどういう解決策が適切かよくわかりませんでしたので一応)
Re: メンバ関数ポインタへの代入
Posted: 2011年8月20日(土) 10:43
by YYSS
回答ありがとうございます。
コード:
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: メンバ関数ポインタへの代入
Posted: 2011年8月20日(土) 12:43
by よしぴー
コード:
(Laser[num].*Laser[num].LaserAct)();
と記述すればOKです。
Re: メンバ関数ポインタへの代入
Posted: 2011年8月20日(土) 13:50
by a5ua
個人的には、関数ポインタを経由してメンバ関数を呼び出す処理を、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);
}
Re: メンバ関数ポインタへの代入
Posted: 2011年8月20日(土) 18:36
by YYSS
回答ありがとうございます。
無事に関数ポインタを実装することが出来、スマートなソースコード?になりました。
また何かあったらよろしくお願いします!