動的2次元配列(new)についてお聞きしたいことが…。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
TJJ

動的2次元配列(new)についてお聞きしたいことが…。

#1

投稿記事 by TJJ » 10年前

現在、私はDXライブラリでRPGをつくってます。マップを管理する際にどうしてもマップデータを動的確保して静的領域に余裕を持たせたいと思ってます。
しかし、以下の内容でプログラムを書き進めることができません。

コード:

class Map{
	int **map;
	int old_limit_h;//動的map[][] 解放用 縦幅
public:
	static void create_map(int,int);//Map variable
	static int view_map(int,int);
	static void input_map(int,int,int);//w,h,data
	static void destruct_map();//Destructing map variable
};

void Map::create_map(int h,int w){
	map = new int*[h]; //<- ここでmapの参照エラーが出てきて困ってます!!以下のmapも参照エラーを起こしてます。
	for (int i = 0; i < h; i++) {
		map[i] = new int[w];
	}
	old_limit_h = h; //<- mapだけではなく old_limit_hも参照エラーを起こしてます。
}

int Map::view_map(int h,int w){
	return (map[h][w]);
}

void Map::input_map(int h, int w, int data){
	map[h][w] = data;
}

void Map:destruct_map(){
	for (int i = 0; i < old_limit_h; i++) {
    delete[] map[i];
	}
	delete[] map;
}
開発環境 VC++ 2008 Express Edition
エラーの内容は

静的でないメンバ 'Map::map' への参照が正しくありません。
静的でないメンバ 'Map::old_limit_h' への参照が正しくありません。
'Map::map': 関数呼び出しには引数リストがありません。メンバへのポインタを作成するために '&Map::map' を使用してください
配列または、ポインタでない変数に添字が使われました。

という内容です。

本やほかのサイトで文法について調べましたが原因が分かりません。

動的確保の仕方が間違っているのでしょうか? ご回答お願い致します。


前回、私の疑問を解決してくださった方、この質問をご覧になっていらっしゃらないかと思いますが、ここでお礼を申し上げます。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#2

投稿記事 by softya(ソフト屋) » 10年前

2次元配列なると解放とか読み込みとか要素へのアクセスとか色々と面倒なので通常は縦x横の1次元配列を使います。
クラスに隠蔽するのなから中の動作が隠せますからね。
x * 縦サイズ + y
で配列の添字は計算出来ます。
と言うことでいかがでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

beatle
記事: 1281
登録日時: 12年前
住所: 埼玉
連絡を取る:

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#3

投稿記事 by beatle » 10年前

Map::mapはインスタンス変数といって、Mapクラスをインスタンス化しないと使えない変数です。
一方でMap::create_mapは静的(=static)関数ですので、Mapクラスをインスタンス化せずに使える関数です。

存在しない変数に書き込もうとしていますのでエラーが出ています。

解決策:
Map::mapをクラス変数にするか、Map::create_mapを静的でない関数にします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#4

投稿記事 by softya(ソフト屋) » 10年前

グローバルなクラスにしたいなら、シングルトンを使われては?
staticは面倒でしょう。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#5

投稿記事 by みけCAT » 10年前

softya(ソフト屋) さんが書きました:2次元配列なると解放とか読み込みとか要素へのアクセスとか色々と面倒なので通常は縦x横の1次元配列を使います。
クラスに隠蔽するのなから中の動作が隠せますからね。
x * 縦サイズ + y
で配列の添字は計算出来ます。
と言うことでいかがでしょうか?
最近自分が思いついた方法では、
1.情報を入れる1次元配列(要素数は縦サイズ×横サイズ)とポインタを入れる1次元配列(要素数は縦サイズ)の2本を確保
2.ポインタを入れる1次元配列のi番目(i=0,1,...,縦サイズ-1)の要素に情報を入れる1次元配列の(i*横サイズ)番目の要素のポインタを代入
3.ポインタを入れる1次元配列を元の情報の2次元配列として利用する
というものがあります。
これで確保の手間の少なさとアクセスの便利さ(掛け算を書かず、普通の2次元配列のように書ける)を両立できると思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

zxc
記事: 79
登録日時: 11年前
住所: 日本の背骨(?)あたり

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#6

投稿記事 by zxc » 10年前

  Mapクラスのメンバ関数は静的ですが、メンバであるmapやold_limit_hは静的ではない(staticで修飾されていない)ですよね。
  main関数や他の関数でどう呼び出しているかわからないので推測ですが、Mapクラスの実体を作らずに関数を使用しようとしたため、実体の無いMap::mapやMap::old_limit_hをその関数で利用することができないと言う旨のエラーではないでしょうか。次からはエラーの番号(と言って良いのか分かりませんが)もぜひ載せてください。

  それとよくわかりませんが、もし質問されてその疑問が解決したにもかかわらず、適切な返答とトピックの解決をされていないのであれば、ここではなく、そのトピックで対応すべきことだと思います。
  

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#7

投稿記事 by softya(ソフト屋) » 10年前

あれ? 過去に質問が残っているんですね。
調べみてました。

「プログラミングの上達方法について • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?f=3&t=12860
「ゲームプログラミングでフローチャートは書くべきですか? • C言語交流フォーラム ~ mixC++ ~」
http://dixq.net/forum/viewtopic.php?t=9586&p=77308
これですね。

質問はからなず解決させて、どのように解決したか、あるいはどのように参考なったか詳細にお書きください。
http://dixq.net/board/board.html
後から見た他の人の参考になるようにお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#8

投稿記事 by ISLe » 10年前

ポインタのポインタによる2次元配列では、
・横幅の加算で縦に移動できない
・静的領域にマップデータを配置できない(ヒープを余分に消費する)
という点が不便です。

アクセサを用意したほうが縦横の順番を気にする必要もなくなりますし。

かずま

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#9

投稿記事 by かずま » 10年前

static の意味を全く理解されていないようですね。
勉強してください。
プログラムですが、次のように書けばいいのでは?

コード:

class Map {
    int **map;
    int old_limit_h;
    Map(int w, int h);
    ~Map();
public:
    static Map *create_map(int w, int h);
    int view_map(int w, int h);
    void input_map(int w, int h, int data);
    void destruct_map();
};
 
Map::Map(int w, int h) : map(0)
{
    map = new int*[h];
    for (int i = 0; i < h; i++) map[i] = new int[w];
    old_limit_h = h;
}
 
Map::~Map()
{
    if (map) {
        for (int i = 0; i < old_limit_h; i++) delete[] map[i];
        delete[] map;
        map = 0;
    }
}

Map *Map::create_map(int w, int h) { return new Map(w, h); }
int  Map::view_map(int w, int h) { return map[h][w]; }
void Map::input_map(int w, int h, int data) { map[h][w] = data; }
void Map::destruct_map() { delete this; }

#include <iostream>
int main()
{
    Map *p = Map::create_map(1920, 1080);
    p->input_map(640, 480, 123);
    std::cout << p->view_map(640, 480) << std::endl;
    p->destruct_map();
}

かずま

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#10

投稿記事 by かずま » 10年前

コンストラクタの : map(0) と、
デストラクタの if (map) と map = 0; は無意味でした。
削除してください。

アバター
usao
記事: 1887
登録日時: 11年前

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#11

投稿記事 by usao » 10年前

オフトピック
複製行為への対策も欲しいですね

かずま

Re: 動的2次元配列(new)についてお聞きしたいことが…。

#12

投稿記事 by かずま » 10年前

static を使わないなら、次のようになります。

コード:

class Map {
    int **map;
    int old_limit_h;
public:
    void create_map(int w, int h);
    int view_map(int w, int h);
    void input_map(int w, int h, int data);
    void destruct_map();
};
 
void Map::create_map(int w, int h)
{
    map = new int*[h];
    for (int i = 0; i < h; i++) map[i] = new int[w];
    old_limit_h = h;
}
 
void Map::destruct_map()
{
    for (int i = 0; i < old_limit_h; i++) delete[] map[i];
    delete[] map;
}

int  Map::view_map(int w, int h) { return map[h][w]; }
void Map::input_map(int w, int h, int data) { map[h][w] = data; }

#include <iostream>
int main()
{
    Map obj;
    obj.create_map(1920, 1080);
    obj.input_map(640, 480, 123);
    std::cout << obj.view_map(640, 480) << std::endl;
    obj.destruct_map();
}

閉鎖

“C言語何でも質問掲示板” へ戻る