ページ 1 / 1
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使ってましたけど、めんどくさかったので
フォルダで管理してました。
ファイル名がぶつかって大変ですけど
いろいろ思い出せました、ありがとうございました