プロが教える店舗&オフィスのセキュリティ対策術

今ゲームを作成中です。クラス型の配列を引数で渡して
その関数内でメンバの値を変えたいと思っています。
下記のような記述を試してみたのですがエラーは出ませんが
配列が関数内で参照できず思うようにいきません。
同じクラス内でクラス型の配列は使えないのでしょうか?
その場合どのようにすれば配列でクラス内メンバの値を
保持すればよいでしょうか?ご回答お願いします。

#define Block_Max (100)

Block* B
Block* BB[]

void main(){
  for(int no=0; no < Block_Max; no++){
    B->Block_Test(no,BB);
  }
}

Block::Block_Test(int no,Block* BB[]){
  BB[no]->B_Test_F = true;
}

A 回答 (3件)

このところ VisualStudio は使っていないので的を外しているかもしれませんが....



void Block::BlockTime(int no,Block* BB[],DWORD g_B_Time) にしろ void Block::Block_Add_End(int no,Block* BB[]) にしろ, 配列 BB はこれらの関数の仮引数になっています. つまり, これらの関数内で「BB」と書けば, それは
Block* BB[BLOCK_ADD_MAX];
と定義した BB ではなく仮引数としての BB です.

ということで, 「BBの中の要素数が表示されていた」という「別のクラス内」で「BB」が仮引数として使われているか確認してください. そちらで仮引数になっていないのであれば, 「仮引数になっているかどうか」が影響するのかもしれません.

あと, 「プログラム上 (プログラムなりに) ちゃんと参照できている」んだけど「デバッガでは参照できていない」という可能性もありますね. この質問をするということは「関数内でメンバの値を変えたいと思ってプログラムを書いているにもかかわらずメンバの値が変わっていない」ということだと思うのですが, デバッガ以外でも「メンバの値がおかしい」ことは確認できていますか?

この回答への補足

すみません、自己解決しました。すごく単純なミスでした!
BB[no]->B_ch_TF == true 代入の場所が==になっていておかしなことに
なっていました!お恥ずかしい・・・。

補足日時:2012/02/25 15:28
    • good
    • 0
この回答へのお礼

回答ありがとうございます!
なるほど、そのまま実態を扱っている訳ではなく仮引数になっていたのですね。
「BBの中の要素数が表示されていた」そのBBの中を確認した場所は仮引数ではなく、
要素数が表示されていないところは仮引数でした。これが原因の元かもしれません。
原因についてなるべく自分で調べてみようと思います。的確な回答をありがとうございました。

関数内でメンバの値を変えたいと言うのはここの関数内で変えていて、書き忘れていました;
やりたいことは落下するブロックが地面に触れて一定時間経過すると種類が変わるといった
処理を実装したいです。


for(int no=0; no<BLOCK_ADD_MAX; no++){
B->B_ChTime(no,BB,1000);  //1秒経過したら変化
if(BB[no]->B_ch_TF == true){
    /*---------------------------------------
     ここでB_ch_TFがtrueになっていないらしく
     変化の処理が行われないのです;
    ----------------------------------------*/
        //変化等処理
}
}


/*---------------------------------------
ブロックチェンジタイム関数
ブロックが地面に触れてから変化
するまでの時間を計測する。
戻り値 なし
引数 番号、ブロック配列、変化の時間
---------------------------------------*/

void Block::B_ChTime(int no,Block* BB[],DWORD B_ch_T){
if(BB[no]->B_ch_F == true){
/*----------------------------
 ここまではブレークポイントで
 止められ、通っていることが
 確認できました。
----------------------------*/
if(BB[no]->InitTime_ch == true){
BB[no]->LastTime_ch = timeGetTime();
BB[no]->InitTime_ch = false;
}
BB[no]->nowtime_ch = timeGetTime() - BB[no]->LastTime_ch;
/*-------------------------------------------
 ここから先にブレークポイント
 を設けたところすべて関数の終わりに
 位置が変更されうまくいかなくなっています;
-------------------------------------------*/
if(BB[no]->nowtime_ch > B_ch_T && BB[no]->B_ch_TF == false){
if( BB[no]->B_ch_F == true ){
BB[no]->B_ch_TF == true;
BB[no]->B_ch_F == false;
}
}
}
}//ブレークポイントの位置(デバッグ停止で元に戻る)



class TimeControl{
   public:
     InitTime_ch   //計測開始
     LastTime_ch   //計測した時間
     nowtime_ch    //経過した時間
}

class Block : public TimeControl {
   public:
     void B_ChTime(int no,Block* BB[],DWORD B_Ch_T);
     bool B_ch_T;         //ブロックが地面に触れたか。
     boolB_ch_TF;//ブロックが変化する時間を超えたか。
     
}


デバッガ以外で確認する方法が思いつかず、if分で目的の値に指定して
中を通ったら― と思っているのですがうまくいきません;
一応B_ch_Fが通っているのでメンバの値全体がおかしいわけではないと思うのですが
そうすると仮引数から値を書き換えていて問題がないことに・・・。

お礼日時:2012/02/25 10:24

「クラス型の配列」などどこにもいません (ある型とその型へのポインタとは全く別物) が....



さておき, こんな一部分だけ見せられてもどうにもならないので, そのような現象を起こす完全なプログラムを出してください.

ああ, 「配列でクラス内メンバの値を保持する」ってのも, どういう意味で使っているのかわからん.

この回答への補足

すみません。プログラムを人に見せたことがなくて;
プログラムがなかったらわからない、当たり前でした。

ツールはVisualStudioを使っています

#define BLOCK_ADD_MAX (100)

TimeControl* g_Time;
Block* B;
Block* BB[BLOCK_ADD_MAX];
DWORD g_B_Time[] = {1.3, 1.8, 2.6, 3.5, 4.9, 6.3, 7.7, 8.9, 9.3, 10.2...}; //100個入ってます。

void Action::GameMain(void)
{
if(InitFlag){
InitGame();
}
BlockWait();



void Action::InitGame(void){
    g_Time = new TimeControl();
B = new Block();
for(int i=0;i < BLOCK_ADD_MAX; i++)
BB[i] = new Block();
InitFlag = false;
}

/*--------------------------------
ブロックウェイト関数
ブロックを時間で出現させる。
戻り値 なし
引数  なし
---------------------------------*/

void Action::BlockWait(void){
for(int no=0;no<BLOCK_ADD_MAX;no++){
B->BlockTime(no,BB,g_B_Time[no]);//時間が経ったらブロックを出現
if(BB[no]->B_add_F == true){
if(no == 10)
BB[no]->B_add_Gra = 1; //ブロックの落下速度増加
if(no == 20)
BB[no]->B_add_Gra = 2;
if(no == 30)
BB[no]->B_add_Gra = 3;
if( no == 40)
BB[no]->B_add_Gra = 4;
B->Block_Gravity_Set(no,true,BB);
B->Block_Add_End(no,BB);
            ... //その他画像、位置、当たり判定等をセット
}
}
}

/*-------------------------------------------------
ブロックタイム関数
ブロックが出現するまでの
時間を計測する。
戻り値 なし
引数 配列番号、ブロックの配列、ブロック出現時間
--------------------------------------------------*/
void Block::BlockTime(int no,Block* BB[],DWORD g_B_Time){
if(BB[no]->InitTime == 1){
BB[no]->LastTime = timeGetTime();
BB[no]->B_add_T = g_B_Time;
BB[no]->InitTime = 0;
}
    BB[no]->nowtime = timeGetTime() - BB[no]->LastTime;
if(BB[no]->nowtime > BB[no]->B_add_T * 1000 && BB[no]->B_add_TF == false){
/*ここでブレーク
 配列BBの中身を見ると
 要素数が表示されていません・・・*/
BB[no]->B_add_F = true; //ブロック出現
}
}


/*--------------------------
タイムクラス
---------------------------*/
class TimeControl{
public:
TimeControl();
~TimeControl();
boolInitTime;
DWORDLastTime;
DWORDnowtime;
      ...
private:
};

/*-------------------------
  ブロッククラス
--------------------------*/
class Block : public TimeControl {
public:
Block();
~Block();
boolB_add_F;//ブロックが追加されたか。
boolB_add_TF;//ブロックが追加される時間が経過したか。
boolB_gra_F;//ブロックに重力がかかっているか。
intB_add_Gra;    //ブロックの重力を加速させるか。
voidB_ChTime(int no,Block* BB[],DWORD B_ch_T);
voidBlockTime(int no,Block* BB[],DWORD g_B_Time);
private:
};


「配列でクラス内メンバの値を保持する」と言うのは1個の配列で
時間などのメンバの値を持てたら便利かなと思って書きました。
紛らわしいことを書いてしまってすみません;

今やりたい処理があったのですがうまくいかず、
ブレークポイントを置いて調べようとしてみたところ勝手に場所が変わってしまいます。
その現象が起こる共通の部分がクラス内でクラス型配列を使っている部分でしたので
もしかしたらと思って質問しました。

補足日時:2012/02/24 16:24
    • good
    • 0
この回答へのお礼

すみません。大事な部分が抜けていました;

void Block::Block_Add_End(int no,Block* BB[]){
  /*ここでブレークポイント
   BBの中身をウォッチ式で
   確認してみると要素が消えています;*/
BB[no]->B_add_F = false;
BB[no]->B_add_TF = true;
}

別のクラス内から参照した時はしっかりとBBの中の
要素数が表示されていたのですが何か関係があるのでしょうか?

お礼日時:2012/02/24 16:32

このソースだけだと、BもBBもポインタ変数が定義されているだけで、クラスのインスタンスがありません。



int* p;

*p=1;

がコンパイルエラーにはならないけど正しく動作しないのと同様です。
あと、グローバル変数を使うなら、同じ変数名を関数の引数に使用するのはやめた方がいいですよ。
    • good
    • 0
この回答へのお礼

すみません。インスタンスの生成を書き忘れていました;

アドバイスありがとうございます!できるだけ引数では別の変数名を使うようにしようと思います。

お礼日時:2012/02/24 16:34

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!