変数を宣言すると何が得られるかを理解することは非常に重要だと思います。のように、実際にメモリに作成されるもの。
では、を見てみましょうSomeClass*** world;
。これはあなたに何をもたらしますか?それはあなたにポインタのマトリックスを手に入れますSomeClass
か?いいえ、そうではありません。実際、これによって1つのものと1つのものだけ(単一のポインター)が得られることを知って驚かれるかもしれません。はい、そうです、たった1つのポインタです。ポインタであるこのworld
変数を定義しました。それから得られるのはそれだけです。その単一のポインタ。
次に、このポインタを使用して、へのポインタを指す他のポインタを指す必要がありますSomeClass
。しかし、それが指し示すものはまだ存在していません。したがって、 20まで繰り返しi
て実行すると、まだ存在していないポインタのマトリックスにアクセスしようとしています。j
world[i][j]
を使用しながら、作成したものを機能させるにSomeClass***
は、ポインタのマトリックスを割り当てる必要があります。
world = new SomeClass**[20];
for (int i = 0; i < 20; i++) {
world[i] = new SomeClass*[20];
}
したがって、最初に20の配列を割り当てSomeClass**
、次にそれらの各ポインターが割り当てられた20の配列を指すようにしSomeClass*
ます。これはあなたが望むものをあなたに与えます...
しかし、待ってください-これは醜いです。これは、C++の記述方法ではありません。理由もなく、非常に多くの動的割り当て。それはまた、あなたがそれを終えたときにあなたがすべてを覚えていなければならないことを意味しますdelete
-そしてそれも醜いです。動的割り当てに依存しない場合、これはすべてはるかに簡単になります。ポインタを使用する代わりに多次元配列を作成するだけで、すでに作業がはるかに簡単になります。
SomeClass* world[20][20];
これworld
で、へのポインタの20x20配列になりますSomeClass
。あなたは実際にそれをメモリに入れます。以前のようにポインタを取得するだけではありません。ポインタの多次元配列全体を取得できます。あなたはラッキーです。
これで、ポインタをまったく使用しないことで、さらに改善することができます。現時点では、オブジェクトを動的に割り当てSomeClass
、配列内のオブジェクトにポインタを固定する必要があります。SomeClass
しかし、代わりにの配列を持ってみませんか?
SomeClass world[20][20];
SomeClass
これで、オブジェクトの多次元配列ができました。人生はこれよりずっと良くなることはありません。手動で何かを割り当てたり削除したりする必要はありません。各要素がすでにSomeClass
オブジェクトであり、サービスの準備ができているメモリ内の多次元配列全体が提供されます。
標準ライブラリのコンテナを使用することで、さらに安全性を向上させることができます。C ++ 03を使用している場合は、を使用できますがstd::vector<std::vector<SomeObject> >
、これは少しやり過ぎかもしれません。ただし、C ++ 11では、従来の配列を使用してきちんと置き換えられ、全体的に安全になるタイプが導入されていますstd::array
。あなたはそれをこのように使うことができます:
std::array<std::array<SomeObject, 20>, 20> world;