ページ 11

iterator を使ってのアクセス

Posted: 2013年1月23日(水) 18:12
by dic
イテレータを使ってvector要素にアクセスしようとすると、実行エラーがでます

Expression : vector iterators imcompatible

とエラーがでますので、vector と iterator の部分なのです、で、以下の while( p != ... のところで
エラーがでます

コード:

// 定義
typedef	struct
{
	POINT	camera;		//	カメラ
	POINT	player;		//	プレイヤー
	int		image;		//	背景画像
	int		image2;		//	プレイヤー画像
	vector<CBlock>	vBlock;	//	ブロックコンテナ
} Param_t;
static	Param_t	g_tParam;

...
......
// エラーの場所
	//	ブロックの描画
	vector<CBlock>::iterator	p;
	p = g_tParam.vBlock.begin();
	while( p != g_tParam.vBlock.end() )  // ここでエラー
	{
		p->Draw();
		p++;
	}
どういったエラーなのでしょうか? よろしくお願いします
Visual C++ 2010 Express
DxLibを使用

Re: iterator を使ってのアクセス

Posted: 2013年1月23日(水) 18:26
by h2so5
これだけではよく分かりません。エラーを再現できる最小限のコードを貼ってください。
検索するとvector iterators imcompatible は別々のインスタンスのvectorのイテレータ同士を比較すると発生するエラーのようです。

Re: iterator を使ってのアクセス

Posted: 2013年1月24日(木) 04:15
by dic
全部張ります

編集 間違えました 貼り付けなおします

コード:

//

#include "stdafx.h"
#include "[2012 12 10] DxLib骨組み.h"

class	CBlock
{
public:
	int		m_x, m_y;
	void	Set( int x, int y );
	CBlock();
	void	Draw();
};

typedef	struct
{
	POINT	camera;		//	カメラ
	POINT	player;		//	プレイヤー
	int		image;		//	背景画像
	int		image2;		//	プレイヤー画像
	vector<CBlock>	vBlock;	//	ブロックコンテナ
} Param_t;
static	Param_t	g_tParam;

CBlock::CBlock() { m_x = m_y = 0; }
void	CBlock::Set( int x, int y )
{
	m_x = x;
	m_y = y;
}
void	CBlock::Draw()
{
	int	x = m_x + g_tParam.camera.x;
	int	y = m_y + g_tParam.camera.y;
	DrawBox( x-16, y-16, x+16, y+16, GetColor(0,0,128), TRUE );
}



//======================================================================================
void	初期化()
{
	memset( &g_tParam, 0, sizeof(g_tParam) );
	g_tParam.image = LoadGraph( _T("yandere.jpg") );
	g_tParam.image2 = LoadGraph( _T("プレイヤー1.bmp") );
}



//======================================================================================
void	描画()
{
	int		w, h;
	GetGraphSize( g_tParam.image, &w, &h );

	//	背景描画
	int		x = 320 - w/2;
	int		y = 240 - h/2;
	x = x - g_tParam.camera.x;
	y = y - g_tParam.camera.y;
	DrawGraph( x, y, g_tParam.image, TRUE );

	//	プレイヤーの描画
	x = g_tParam.player.x - g_tParam.camera.x + 320;
	y = 240;
	DrawGraph( x, y, g_tParam.image2, TRUE );

	//	ブロックの描画
	vector<CBlock>::iterator	p;
	p = g_tParam.vBlock.begin();
	while( p != g_tParam.vBlock.end() )
	{
		p->Draw();
		p++;
	}

	//	デバック情報
	DrawFormatString( 0, 20, GetColor(255,0,0), _T("Camera:(%d,%d)"), g_tParam.camera.x, g_tParam.camera.y );
	DrawFormatString( 0, 40, GetColor(255,0,0), _T("Player:(%d,%d)"), g_tParam.player.x, g_tParam.player.y );
}


//======================================================================================
void	動作()
{
	if( 1 == CheckHitKey(KEY_INPUT_UP) )
	{
		g_tParam.camera.y -= 10;
		g_tParam.player.y -= 10;
	}
	if( 1 == CheckHitKey(KEY_INPUT_DOWN) )
	{
		g_tParam.camera.y += 10;
		g_tParam.player.y += 10;
	}
	if( 1 == CheckHitKey(KEY_INPUT_LEFT) )
	{
		g_tParam.camera.x -= 10;
		g_tParam.player.x -= 10;
	}
	if( 1 == CheckHitKey(KEY_INPUT_RIGHT) )
	{
		g_tParam.camera.x += 10;
		g_tParam.player.x += 10;
	}
	if( 1 == CheckHitKey(KEY_INPUT_SPACE) )
	{
		CBlock	block;
		block.Set( g_tParam.player.x, g_tParam.player.y );
		g_tParam.vBlock.push_back( block );
	}
}



//======================================================================================
int		メインループ()
{
	int		result = 0;
	static	int	mode = 0;

	switch( mode )
	{
	case 0:
		初期化();
		mode = 10;
		break;
	case 10:
		描画();
		動作();
		break;
	}

	return result;
}

int APIENTRY _tWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
{
	ChangeWindowMode( TRUE );

	if( DxLib_Init() == -1 )		// DXライブラリ初期化処理
	{
		return -1 ;			// エラーが起きたら直ちに終了
	}

	//	描画先を裏にする
	SetDrawScreen( DX_SCREEN_BACK );

	//	メインループ
	while( ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE)==0 )
	{
		//	画面をクリアする
		ClearDrawScreen();

		DrawString( 100, 100, _T("DxLib デフォルト"), GetColor(0,255,255), 0 );

		if( メインループ() == -1 )
			break;

		ScreenFlip();
	}

	DxLib_End();

	return 0;
}




Re: iterator を使ってのアクセス

Posted: 2013年1月24日(木) 09:26
by Blue
>>memset( &g_tParam, 0, sizeof(g_tParam) );
ここがまずいんでない?
vectorはクラスなんで単純にmemsetで初期化はできないかと。

Re: iterator を使ってのアクセス

Posted: 2013年1月24日(木) 10:19
by dic
>>Blueさん
そうなんですか、ゼロにすればいいものかと思っていました
ほかのにしたらうまくいきました

Re: iterator を使ってのアクセス

Posted: 2013年1月24日(木) 10:36
by softya(ソフト屋)
C++を扱うときにmalloc,memset,memcpyなどメモリを直接扱うものは避けてください。クラス関係は、この処理ではうまう処理出来ません。C++は使えないと思ってくれたほうが安全です。
それとstrcpyなど文字列関係も封印してstringを使いましょう。

Re: iterator を使ってのアクセス

Posted: 2013年1月24日(木) 16:10
by dic
>>softyaさん
なるほど、メモリ関係は使えないと思っていたほうがいいんですね
ZeroMemory も試したのですがダメですね

strcpy をなるべく使わないということは
string の演算子を使うんですね

なかなか最初はうまくいかないかもしれないですが、なるだけやってみます

Re: iterator を使ってのアクセス

Posted: 2013年1月24日(木) 18:08
by h2so5
この場合は構造体のコンストラクタを使って初期化をするのが妥当ではないでしょうか。

Re: iterator を使ってのアクセス

Posted: 2013年1月24日(木) 20:10
by dic
>>h2so5さん
構造体にコンストラクタが定義できるとは知りませんでした
以下に変更したものを貼り付けておきます

これは便利

コード:


struct	Param_t
{
	Param_t()
	{
		camera.x = camera.y = 0;
		player.x = player.y = 0;
		image = 0;
		image2 = 0;
		vBlock.clear();
	}
	POINT	camera;		//	カメラ
	POINT	player;		//	プレイヤー
	int		image;		//	背景画像
	int		image2;		//	プレイヤー画像
	vector<CBlock>	vBlock;	//	ブロックコンテナ
};

Re: iterator を使ってのアクセス

Posted: 2013年1月24日(木) 20:21
by h2so5
vectorをclear()でわざわざ初期化する必要はありません。最初から空ですから。

Re: iterator を使ってのアクセス

Posted: 2013年1月24日(木) 21:42
by salsaww
C++だと、”Cの構造体”とは違って、構造体はclassのデフォルトのprivateがpublicになってるかどうかですからね。
もうちょっと、詳しく説明すると、structは、classの時にできる継承なんかも可能です。もちろん要素へのアクセスをprivateとか変更も可能。
参考までに。

コード:

#include<iostream>

struct a{ int point;};
struct b : a{};

int main()
{
	a* beta = new b();
	beta->point=100;
	std::cout<< beta->point <<std::endl;
	return 0;
}
あと、class内のfiledの初期化に関しては、*必*要*な*ら*ば* 初期化子を使う事をお勧めします。
定義した順とかとか、色々と面倒な事があったりしますが……

Re: iterator を使ってのアクセス

Posted: 2013年1月25日(金) 07:00
by beatle
dic さんが書きました:

コード:


struct	Param_t
{
	Param_t()
	{
		camera.x = camera.y = 0;
		player.x = player.y = 0;
		image = 0;
		image2 = 0;
		vBlock.clear();
	}
	POINT	camera;		//	カメラ
	POINT	player;		//	プレイヤー
	int		image;		//	背景画像
	int		image2;		//	プレイヤー画像
	vector<CBlock>	vBlock;	//	ブロックコンテナ
};
僕ならこう書きますよっと。

コード:

struct  Param_t
{
    Param_t() :
        camera(0, 0), player(0, 0), image(0), image2(0), vBlock()
    { }
    POINT   camera;     //  カメラ
    POINT   player;     //  プレイヤー
    int     image;      //  背景画像
    int     image2;     //  プレイヤー画像
    vector<CBlock>  vBlock; //  ブロックコンテナ
};
# POINT構造体にもコンストラクタが定義されていることを前提としています。

それから、ヘッダファイルの名前が
[2012 12 10] DxLib骨組み.h
などと、恐らくファイルをコピーして名前を変えてバックアップをしているのだと思いますけど、
もし気が向けばGitなどのバージョン管理ツールを勉強して使うことをおすすめいたします。
(既にご使用中ならごめんなさい)

Re: iterator を使ってのアクセス

Posted: 2013年1月25日(金) 17:03
by dic
なるほど、vB lock.clear() はいらないですね
しかし、仮に tParam g_tParam2; と・・・使うとき・・・は、うん、vBlock.clear() は使用しないですね


初期化子も、初めて知りました。特に順番があるとは・・・複雑
ちょろっと見たことがあったきがするけど、そこまでは使わなかったですね


ソースコード管理はSVN使ってましたけど、めんどくさかったので
フォルダで管理してました。
ファイル名がぶつかって大変ですけど


いろいろ思い出せました、ありがとうございました