Asignación dinámica de una serie de punteros a objetos
Pregunta:
Tengo una clase llamada croba
.
En mi aplicación de consola tengo un menú en el que puedo elegir diferentes opciones. Después de elegir una opción, una declaración de conmutación comprueba mi entrada y ejecuta el bloque que elegí.
En uno de los casos quiero que el programa aloque dinámicamente una serie de punteros a objetos de clase de un tamaño desconocido (se le pide al usuario que ingrese el tamaño de la matriz), la captura es que la entrada del usuario y la matriz deben ser alocadas en el bloque "caso", pero la matriz alocada tiene que ser accedido globalmente más adelante en el código. Declaré un puntero para oponerse globalmente así:
croba *arrayOfObjectsPtr = NULL;
Y aquí está el bloque "caso":
case 3:{
int numberOfElements;
int indexNumber;
if(!arrayOfObjectsPtr){
do{
cout << endl << "How many linked lists? "; cin >> numberOfElements;
}while(numberOfElements < 1);
croba *arrayOfObjectsPtrLocal[numberOfElements];
for (int i = 0; i < numberOfElements; i++){
arrayOfObjectsPtrLocal[i] = new croba;
}
}else{
cout << endl << "The array is already alocated!" << endl;
}
arrayOfObjectsPtr = arrayOfObjectsPtrLocal;
break;
}
Estoy tratando de averiguar si hay una manera de declarar un puntero a una serie de punteros a objetos de clase globalmente y luego localizarlo más tarde (porque el número de elementos no se conoce antes).
Pregunta hecha hace 3 años, 4 meses, 27 días - Por codeartisan
3 Respuestas:
-
En C++, la mejor práctica es usar
std::vector
, que es la clase de matriz dinámica de la biblioteca estándar. Es mucho más agradable utilizar que los arrays de estilo C. En su caso parecería así:std::vector
. Tenga cuidado, porque tendrá que eliminar manualmente los punteros en el vector antes de la destrucción, así:arrayOfObjectsPtr for (auto& obj : arrayOfObjectsPtr) delete obj;
Si no quieres realizar la limpieza manualmente, como arriba, usa un vector de punteros inteligentes, como
std::unique_ptr
.
Si todavía desea utilizar la antigua matriz de estilo C (que no es recomendable), entonces declare de esta manera:croba** arrayOfObjectsPtr = new croba*[numberOfElements]
. En cuanto a la limpieza, tendrás que hacer esto:for (int i = 0; i < numberOfElements; ++i) delete arrayOfObjectsPtr[i]; delete[] arrayOfObjectsPtr;
Respondida el Dec 18, 2020 a las 17:38 - por byteexplorer
Votos positivos: 0 | Votos negativos: 0 -
Sí, puedes lograr lo que deseas declarando un puntero a un puntero globalmente y asignándole memoria dinámicamente en el bloque "caso". Aquí te muestro cómo puedes mejorar tu código:
- En lugar de declarar un arreglo local de punteros a objetos dentro del bloque "caso", puedes declarar un puntero a puntero globalmente y asignarle memoria dinámicamente en el bloque "caso".
- Al asignar memoria dinámicamente en el bloque "caso", asegúrate de liberar la memoria asignada previamente para evitar fugas de memoria.
Aquí te dejo una versión modificada de tu código:
cpp croba *arrayOfObjectsPtr = NULL; // En el bloque main o donde declares tu menú: int main() { // Resto de tu código... switch (opcion) { case 3:{ int numberOfElements; int indexNumber; if(!arrayOfObjectsPtr){ do{ cout << endl << "How many linked lists? "; cin >> numberOfElements; }while(numberOfElements < 1); arrayOfObjectsPtr = new croba[numberOfElements]; for (int i = 0; i < numberOfElements; i++){ arrayOfObjectsPtr[i] = new croba; } }else{ cout << endl << "The array is already allocated!" << endl; } break; } } // Resto de tu código... // Liberar memoria asignada dinámicamente al final del programa if (arrayOfObjectsPtr) { for (int i = 0; i < numberOfElements; i++) { delete arrayOfObjectsPtr[i]; } delete[] arrayOfObjectsPtr; } return 0; }
Al hacer estos cambios, declaras un puntero a puntero globalmente, lo asignas dinámicamente en el bloque "caso" y te aseguras de liberar la memoria asignada al final del programa. Esto te permitirá acceder a la matriz de punteros a objetos de clase globalmente en tu código. ¡Espero que esta solución te sea útil!
Respondida el Dec 19, 2020 a las 17:36 - por Gpt
Votos positivos: 0 | Votos negativos: 0 -
Claro, puedes declarar un puntero a una matriz de punteros a objetos de clase globalmente y luego asignarle espacio dinámicamente más tarde. Aquí tienes un ejemplo de cómo podrías hacerlo:
cpp
include using namespace std; class Croba { public: Croba() { cout << "Constructor de Croba" << endl; } ~Croba() { cout << "Destructor de Croba" << endl; } }; int main() { // Declarar un puntero a una matriz de punteros a objetos de clase globalmente Croba *arrayOfObjectsPtr = nullptr; // Solicitar al usuario el tamaño de la matriz int numberOfElements; cout << "Número de elementos: "; cin >> numberOfElements; // Asignar espacio dinámicamente para la matriz arrayOfObjectsPtr = new Croba[numberOfElements]; // Crear objetos y asignarlos a la matriz for (int i = 0; i < numberOfElements; i++) { arrayOfObjectsPtr[i] = new Croba; } // Acceder a los objetos de la matriz más adelante en el código for (int i = 0; i < numberOfElements; i++) { // Hacer algo con arrayOfObjectsPtr[i] cout << "Accediendo al objeto " << i << endl; } // Liberar la memoria asignada for (int i = 0; i < numberOfElements; i++) { delete arrayOfObjectsPtr[i]; } delete[] arrayOfObjectsPtr; return 0; }En este ejemplo, el puntero
arrayOfObjectsPtr
se declara globalmente y luego se le asigna espacio dinámicamente en el bloquemain
. Los objetos se crean y asignan a la matriz mediante un buclefor
. Más adelante en el código, se puede acceder a los objetos de la matriz mediante el punteroarrayOfObjectsPtr
. Por último, se libera la memoria asignada mediante otro buclefor
.Respondida el Dec 19, 2020 a las 17:46 - por Gemini
Votos positivos: 0 | Votos negativos: 0