2011-12-11 1 views
14

オブジェクトがコンストラクタのために渡される必要があるときに、オブジェクトの配列を作成できるかどうかは疑問でした。C++のコンストラクタを使ってオブジェクトの配列を動的に宣言する方法

MyClass *myVar; 
myVar = new MyClass[num]; // I would like to specify the array size after declaration 
int i = 0; 
for(i = 0;i < num;i++) 
    myVar[i] = new MyClass(0,0); // I would also like to populate the array with new objects 

私はこれが機能することを知っている:

MyClass *myVar; 
myVar = new MyClass[num]; 

しかし、コンストラクタがそれに渡された何もしていたときに、これが唯一の作品、私はこのような何かをしたいです。私は何をしようとしていますか?もしそうなら、どうすればいいですか?

EDIT:配列の使用方法を知りました。私はそれをどうやってしたのですか:

私はベクトルなどを使用しますが、私の先生は可能な限り基本配列を使用するように私たちに教えてくれました。上記の解決策は私の先生が書いたコードから実際に得たものです。あなたの助けをありがとう!

答えて

21
MyClass *myVar; 
myVar = new MyClass[num]; 

実際にこのフォームでは、パラメータを取るコンストラクタを呼び出すことはできません。言語仕様では許可されていません。しかし

、あなたは私はあなたが使用することをお勧めしますstd::vectorを、使用している場合、のようにデフォルト以外のコンストラクタを呼び出すベクトルを作成することができます:それはnum要素のベクトルを作成し

#include <vector> //header file where std::vector is defined 

std::vector<MyClass> arr(num, MyClass(10,20)); 

、各要素が作成されますクラスのコピーコンストラクタを呼び出して、MyClass(10,20)を引数として渡します。

このベクターは、あなた自身でメモリを管理する必要がなくなったので、いいです。手動割り当ても手動割り当て解除もありません。さらに、いつでもarr.size()を呼び出して要素の数を知ることができます。あなたはいつもベクトルが含んでいる要素の数を知っています。

arr.push_back(MyClass(20,30)); 

そして今、あなただけのインデックスを使用することにより、すなわち、あなたのアクセス配列、同様に、要素にアクセスすることができます:

さらに
f(arr[i]); // 0 <= i < arr.size(); 

、あなたはまた、単に.push_back()メンバ関数を呼び出すことで、いつでも要素を追加することができます

#include <algorithm> //header file where std::for_each is defined 

std::for_each(arr.begin(), arr.end(), f); 

wher:として<algorithm>ヘッダから種々のアルゴリズム関数を使用することを可能にする、慣用的なプログラミングを容易にイテレータを使用することができe fは、で何をしたいかによって、タイプMyClass&(またはMyClass const &)の1つの引数をとる関数です。

C++ 11では、あなたにラムダを使用することができます。

std::for_each(arr.begin(), arr.end(), [](const MyClass & m) 
             { 
              //working with m 
             }); 
+1

ありがとうございました!私は先生がクラスを代わりに使用したいので、実際にベクトルの代わりに配列を使ってアプローチを探していました。私は答えを見つけた。 – user972276

+0

@ user972276:配列の場合、デフォルトでないコンストラクタを呼び出す場合は、まず最初に行うことができます。しかし、将来、配列が必要な場合は、* std :: vectorを使用することを検討してください。それはクールな機能をたくさん持つ素晴らしい容器です。 – Nawaz

6

をC++ 0xのでは、この文法は動作しますが、新しい表現で、デフォルト以外のコンストラクタを呼び出すことができた。

MyClass *myVar; 
myVar = new MyClass[2]{{10, 20},{20, 30}}; 

しかし、実行時にのみ利用可能な要素の数がある場合は、それが動作するかどうかは疑問です。

Nawazの答えに示されているように、ベクターアプローチはより良いでしょう。

2

これまで私がこれまで行ってきた方法の1つは、ダブルポインタを使用することです。

MyClass ** myvar; 
myvar = new Myclass*[num] 
for(int i = 0; i < 4; i++){ 
*(myvar+i) = new Myclass(i);} 

あなたが想像できるほとんどすべての制御構造を持つ作品、唯一の後退は、オブジェクトは必ずしもヒープ上の連続であることを行っていないということです。

0

実は、あなたがこれを処理するための新しい配置を使用することができます。

MyClass * myVar; 
myVar = reinterpret_cast<MyClass *>(new char[num * sizeof(MyClass)]); 
int i = 0; 
for (i = 0; i < num; i++) { 
    new(&myVar[i]) MyClass(0,0); 
} 
+0

'new char []'の代わりに 'std :: aligned_storage'を使うべきです。 –

+0

また、このメモリを解放するには、各オブジェクトのデストラクタをループして呼び出す必要があり、 'delete [] reinterpret_cast (myVar);を呼び出す必要があります。 –

0

あなたもこのような何かを行うことができます:あなたは助けるために

MyClass *myVar[num]; 

for(int i = 0; i < num; i += 1) 
{ 
    myVar[i] = new MyClass(0, 0); 
} 
関連する問題