ページ 11

ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 12:33
by OROCHI
こんにちは、現在以下のようなコードがあります

コード:

void Renderer::renderScene2( Task* pScene1, Task* pScene2 ) {
	if (pScene1 == 0 || pScene2 == 0) {
		return;
	}

	// ビューポートと深度バッファ(バックバッファ)のクリアとステンシルバッファの削除
	if ( FAILED( pD3DDevice_->Clear( 0, NULL, 		// クリアする領域は全面
		D3DCLEAR_STENCIL |							// ステンシルバッファをクリア
		D3DCLEAR_TARGET |							// バックバッファを指定
		D3DCLEAR_ZBUFFER, 							// 深度バッファ(Zバッファ)を指定
		D3DCOLOR_XRGB(0, 0, 255), 					// クリアする色
		1.0f, 										// クリアする深度バッファ(Zバッファ)の値
		0 ) ) ) {									// クリアするステンシルバッファの値
		return;
	}

	// 描画開始宣言
	if (SUCCEEDED(pD3DDevice_->BeginScene())) {

		// モデルなどの描画
		pScene1->draw(pD3DDevice_);
		// モデルなどの描画
		pScene2->draw(pD3DDevice_);

		// 描画終了宣言
		pD3DDevice_->EndScene();
	}
	// 描画結果の転送
	if (FAILED(pD3DDevice_->Present(0, 0, 0, 0))) {
		// デバイス消失から復帰
		pD3DDevice_->Reset(&d3DPP_);
	}
}

// 呼び出すとき
Task     task[2];
renderScene2( &task[ 0 ], &task[ 1 ]);
要はTask型クラスのpScene1とpScene2を描画するプログラムです。ところが、最終的には描画対象が100個以上まで跳ね上がる予定です。この書き方ではその分だけ引数とDrawを継ぎ足さなくてはならないので、流石に現実的ではありません
ということで、以下のようにポインタの配列を引数に渡すようにしたのですが、呼び出すときにどう書いたらいいのかが分かりません
書き方が分かる方、ご教授願えませんでしょうか?(NUMOFOBJECTは0を超える任意の整数と考えてください)

コード:

void Renderer::renderObject(  Task *pTask[ NUMOFOBJECT ] ){
	// NULLチェック
	for ( int i = 0; i < NUMOFOBJECT; ++i ) {
		if ( pTask[ i ] == 0){
			return;
		}
	}

	// ビューポートと深度バッファ(バックバッファ)のクリアとステンシルバッファの削除
	if (FAILED(pD3DDevice_->Clear( 0, NULL, 			// クリアする領域は全面
		D3DCLEAR_STENCIL |								// ステンシルバッファをクリア
		D3DCLEAR_TARGET |								// バックバッファを指定
		D3DCLEAR_ZBUFFER, 								// 深度バッファ(Zバッファ)を指定
		D3DCOLOR_XRGB( 0, 0, 255 ), 					// クリアする色
		1.0f, 											// クリアする深度バッファ(Zバッファ)の値
		0 ) ) ) {										// クリアするステンシルバッファの値
		return;
	}

	// 描画開始宣言
	if ( SUCCEEDED( pD3DDevice_->BeginScene( ) ) ) {
		// モデルなどの描画
		for (int i = 0; i < NUMOFOBJECT; ++i) {
			pTask[i]->draw( pD3DDevice_ );
		}
		// 描画終了宣言
		pD3DDevice_->EndScene();
	}
	// 描画結果の転送
	if (FAILED(pD3DDevice_->Present(0, 0, 0, 0))) {
		// デバイス消失から復帰
		pD3DDevice_->Reset(&d3DPP_);
	}
}

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 13:03
by usao
普通に渡せば良いのではないでしょうか.

コード:

//int配列(の先頭)を関数引数に渡す
void func( int arg[] );

int A[5] = { 0 };
func( A );

//int*配列〃
void func( int *arg[] );

int *P[5] = { 0 };
func( P );

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 15:02
by OROCHI
渡すのはそれで済んだのですが、渡すものがintではなくクラスなので、定義した後の処理でハンドルされない例外が発生してしまうみたいです。(下記はメンバ変数を初期化するだけの処理です)
こちらの原因はわかりますでしょうか?

コード:

Task	*task[NUMOFOBJECT];
	
for ( int i = 0; i < NUMOFOBJECT; ++i ) {
	task[i]->init();                               // ここで例外発生
}

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 15:56
by usao
>渡すものがintではなくクラスなので

すみません.おっしゃられている意味がよくわかりません.
このことに どれだけの差がある という事をおっしゃられているのでしょうか?


>例外

コレ↓と同じことが起こっているというわけではなくて,でしょうか?

コード:

Task *pTask;
pTask->init();  //おおっと…!

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 16:13
by OROCHI
あ、まさしく例外のことが起こってます(汗

ポインタだからインスタンスはまだ生成されてないですね。

コード:

Task    *task[NUMOFOBJECT];
    
for ( int i = 0; i < NUMOFOBJECT; ++i ) {
    task[i] = new Task();
    task[i]->init();                              
}

で例外問題は回避できますが、こうなると最初の問題に戻って関数を呼ぼうとすると

コード:

renderobject(task);
と書くと、「関数呼び出しの引数が多すぎます」となりエラーが出ます。
・・・やっぱり100個引数を用意して100回drawするしか手がないのでしょうか?

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 16:40
by usao
>「関数呼び出しの引数が多すぎます」となりエラーが出ます。

renderobject()の宣言あたりが間違っているのではないでしょうか?
例えば
void renderobject();
みたいになってるとか.

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 16:45
by softya(ソフト屋)
Task *task[NUMOFOBJECT];
の個々の要素がちゃんとnewされているか気になったのですが。

あっタイミング外しまくっている。失礼しました。

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 16:50
by usao
こんな感じに書きたいのですよね?

コード:

//なにかしらクラス
class Test
{
public:
    Test(){ m_Val = ms_NextVal++;   }
public:
    void Method(){  std::cout << m_Val << std::endl;    }
private:
    int m_Val;
    static int ms_NextVal;
};
int Test::ms_NextVal = 0;

//ポインタの配列で受け取って,メソッドを呼ぶ関数
void Func( Test *pTests[], size_t n )
{
    for( size_t i=0; i<n; i++ )
    {
        pTests[i]->Method();
    }
}

//
int main( int argc, char **argv )
{
    //ポインタの配列 の各要素(ポインタ)が,ちゃんとインスタンスを指す形になってて…
    Test *pTests[ 3 ] = { 0 };
    for( int i=0; i<3; i++ )
    {
        pTests[i] = new Test;
    }

    //関数に渡す
    Func( pTests, 3 );

    //※省略するけど,deleteもちゃんとしましょう.

    std::cout << "[end]" << std::endl;
    std::cin.ignore();
    return 0;
}

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 16:52
by OROCHI
そのときの形が

コード:

void renderObject( Task* pTask[ NUMOFOBJECT ] );
になっていました。

コード:

void renderObject( Task* pTask[ ] );
に修正することで、無事に直りました。ありがとうございました

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 17:08
by usao
>void renderObject( Task* pTask[ NUMOFOBJECT ] );

となっていても そんなエラーは発生しないように思うのだけれど……?

Re: ポインタ型の配列を引数に渡した時の書き方

Posted: 2014年6月11日(水) 17:14
by softya(ソフト屋)
>void renderObject( Task* pTask[ NUMOFOBJECT ] );
OROCHI さん、ヘッダと実体の定義が違っているというのは無かったのでしょうか?