2011-12-11 29 views
14

Me preguntaba si era posible crear una matriz de objetos cuando el objeto necesita que el constructor los transfiera. Quiero algo como esto:cómo declarar dinámicamente una matriz de objetos con un constructor en 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 

sé que esto funciona:

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

pero esto sólo funciona cuando el constructor tiene nada pasaba en ella. ¿Es lo que estoy tratando de hacer posible? Si es así, ¿cómo lo hago?

EDIT: descubrí cómo hacerlo con el uso de matrices. Aquí es cómo lo hice:

MyClass **myVar; 
myVar = new MyClass *[num]; 
for(i = 0;i < num;i++) 
    myVar[0] = new MyClass(0,0); 

me gustaría utilizar vectores y tal, pero mi profesor nos ha dicho que utilizar matrices básicas siempre que sea posible. La solución anterior que obtuve de algún código que mi maestra escribió. ¡Gracias por toda tu ayuda!

Respuesta

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

En realidad, en este formulario no puede invocar el constructor que toma el parámetro (s). No está permitido por la especificación del idioma.

Sin embargo, si se utiliza std::vector, que recomiendo su uso, a continuación, puede crear un vector llamar al constructor no predeterminado como:

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

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

Se crea un vector de num elementos, se crea cada elemento llamando al copy-constructor de la clase, pasando MyClass(10,20) como argumento.

El vector también es bueno porque ahora no necesita administrar la memoria usted mismo. Ni asignación manual ni desasignación manual. Además, puede conocer la cantidad de elementos llamando al arr.size() en cualquier momento. Usted siempre sabe cuántos elementos contiene el vector. También puede agregar elementos en cualquier momento, simplemente llamando a la función .push_back() miembro como:

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

Y ahora se puede acceder a los elementos, al igual que de acceso a conjunto, es decir, utilizando el índice:

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

Además, puede usar iteradores que facilitan la programación idiomática, que le permite utilizar varias funciones algorítmicas de <algorithm> encabezado como:

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

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

RCEst e f es una función que toma un argumento del tipo MyClass& (o MyClass const &) según lo que desee hacer en f.

En C++ 11, se puede utilizar como lambda:

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

Gracias por su ayuda! De hecho, estaba buscando un enfoque usando matrices en lugar de vectores porque mi profesor quería que la clase usara matrices en su lugar. Encontré la respuesta sin embargo. – user972276

+0

@ user972276: para las matrices, su primer enfoque es lo que se puede hacer, si desea invocar un constructor no predeterminado. Sin embargo, en el futuro, si alguna vez necesitas una matriz, * primero * considera usar 'std :: vector'. Es un contenedor impresionante, con muchas características interesantes. – Nawaz

6

En C++ 0x, esta gramática funciona, lo que puede llamar al constructor no predeterminado en la nueva expresión:

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

Pero dudo si funciona cuando la cantidad de elementos está disponible solo en tiempo de ejecución.

El enfoque vectorial sería mejor, como se muestra en la respuesta de Nawaz.

2

Una forma en que he hecho esto en el pasado es usar un doble puntero.

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

Funciona con casi cualquier estructura de control se puede imaginar, el único inconveniente es que los objetos no necesariamente van a ser consecutivos en el montón.

0

En realidad, se puede utilizar una nueva colocación de manejar esto:

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

Debe usar 'std :: aligned_storage' en lugar de' new char [] '. –

+0

También se debe mencionar que para liberar esta memoria debe recorrer y llamar a los destructores de cada objeto y luego llamar a 'delete [] reinterpret_cast (myVar);'. –

0

Usted puede hacer algo como esto también:

MyClass *myVar[num]; 

for(int i = 0; i < num; i += 1) 
{ 
    myVar[i] = new MyClass(0, 0); 
} 
Cuestiones relacionadas