ページ 11

<質問>あるクラス内の関数で同クラスの別関数を使用できるか?

Posted: 2010年9月13日(月) 16:39
by LUNA
かなり久しぶりの投稿です。
今回みなさんに伺いたいのは、あるクラスがあるとして、そのクラスの関数内で同じクラス内の別の関数が使用できるかどうかです。
現在私は学校のプログラムでひとつに繋がったプログラムをファイル分けしてコンパクトにしようとしているんですが、その中で

//------------------------------------------------------------------------------------------
// 関数名:SmokeInit      SmokeInit(gl_Ball.Pos,16,20.0f,0,0,0);
// 内 容:煙更出現処理
//------------------------------------------------------------------------------------------
void SmokeInit(D3DXVECTOR3 Pos,int AniStart,float Size,int RotXRand,int RotZRand,int MoveFlg)
{
    SMOKE        *p;
    D3DXMATRIX    RotMx;
    D3DXVECTOR3    RotAxis;

    p = (SMOKE *)malloc(sizeof(SMOKE));
    if(p != NULL){
        p->Pos = Pos;
        p->Ani = AniStart;
        p->Size = Size;
        p->ACnt = 0;
        p->RotX = ((float)(rand()%(RotXRand*2+1))-RotXRand)/10;
        p->RotZ = ((float)(rand()%(RotZRand*2+1))-RotZRand)/10;
        p->Speed = 0;

        if(MoveFlg != 0){
            RotAxis = p->Pos - gl_LookVec;
            p->Speed = (((float)(rand()%30+20))/100);
            p->Move = D3DXVECTOR3(0,1,0);

            D3DXMatrixRotationAxis(&RotMx,&RotAxis,D3DXToRadian(rand()%360));
            D3DXVec3TransformCoord(&p->Move , &p->Move , &RotMx);
        }

        ZSortInit(p,SmokeDraw,SmokeUpdate,p->Pos);<----ここ。記述してある2つの関数は共にアドレス
    }
}



と、SmokeInit内で同系列のSmokeDraw,SmokeUpdateアドレスを記述してあるのを見つけました。
Smoke関連(Init,Update,Draw)を一つのクラスにまとめようとしたらそのクラス内の関数で同じクラスで別の関数を使用することになってしまいます。記述もややこしくなるだろうし、何よりもそんなことが可能なのか、どうかが分からなくて困っています。もしわかる方がいらっしゃれば、アドバイスしていただけると幸いです。
もし出来る場合は記述方法も教えていただけると幸いです。下手な説明ですみません。これだけだと分かりにくいと思いますので一応元のプログラムをつけときます。これはエラーを起こさずにちゃんと動いたものです。

Re:<質問>あるクラス内の関数で同クラスの別関数を使用できるか?

Posted: 2010年9月13日(月) 17:50
by MNS
>あるクラスがあるとして、そのクラスの関数内で同じクラス内の別の関数が使用できるかどうか
できます。
使うだけなら別にややこしくはありません。

class Smoke
{
void Update();
void Draw();
public:
void Init(){
Update();
Draw();
}

Smoke();
~Smoke();
};


質問は、恐らく、メンバ関数のポインタの扱いについでだと思います。
可能ではありますが、記述が厄介です。
まず、メンバ関数ポインタの型についてですが、上のSmokeクラスを例にとると、
UpdateおよびDraw関数の型は、"void(Smoke::*A)()"などとなります。
アドレスを渡すときは、&Smoke::Update; と記述して渡します。

問題は、その呼出についてです。
たとえば、
void Call(void(Smoke::*A)(), void(Smoke::*B)());
という関数を作り、それにUpdateとDrawのアドレスを渡すとすると、
Call(&Smoke::Update, &Smoke::Draw);
という記述になりますが、
このCall関数がSmokeクラスのメンバ関数か否かで変わってきます。
なぜなら、メンバ関数ポインタでメンバ関数を呼び出すとき、
インスタンスを通じて呼び出す必要があるからです。
メンバ関数であれば、
void Smoke::Call(void(Smoke::*A)(), void(Smoke::*B)())
{
(this->*A)();
(this->*B)();
}
という記述で引数にとった関数を呼び出すことが出来ます。
メンバ関数でなければ、
void Smoke::Call(void(Smoke::*A)(), void(Smoke::*B)(), Smoke* p_smoke)
{
(p_smoke->*A)();
(p_smoke->*B)();
}
や、
void Smoke::Call(void(Smoke::*A)(), void(Smoke::*B)())
{
Smoke smoke;
(smoke.*A)();
(smoke.*B)();
}
などという記述になりますが、後者は恐らく使えないでしょう。

Re:<質問>あるクラス内の関数で同クラスの別関数を使用できるか?

Posted: 2010年9月13日(月) 23:02
by LUNA
へたくそな説明にもかかわらず回答してくれてありがとうございます。
今までエラーが潰せないと思ったら、アドレスだと表記がややこしくなるんですね・・・
まだ理解できてない部分(というか夏休みによるボケが抜けてない)もあるのでじっくりと理解させてもらいます。
本当に回答してくれてありがとうございます。