una resueltos relaciones programacion orientada objetos miembros entre ejercicios constructores codigo clases clase asociacion c++ vector default-constructor

c++ - resueltos - ¿Por qué los elementos de std:: vector no necesitan un constructor por defecto?



relaciones entre clases c++ (3)

¿Y cómo puedo escribir mi propia clase de matriz para no necesitar un constructor predeterminado para sus elementos? En este momento, cuando hago lo nuevo [] para asignar espacio, necesito un constructor predeterminado.

std :: vector no.

¿Cómo hacen esta magia?


Podría asignar un bloque de bytes, luego usar la ubicación new para hacer una nueva instancia de T (su tipo paramétrico) mediante el constructor de copia (no el constructor predeterminado, por supuesto) cuando los elementos nuevos se colocan en la parte posterior del vector. Esto no permitirá hacer "un vector de N Ts inicializados por defecto" (lo que std :: vector puede hacer, por lo que necesita que T tenga un constructor predeterminado para este fin), pero podría crear vectores que comiencen vacío y puede tener Ts empujados sobre ellos.


std::vector no necesita el constructor predeterminado porque nunca lo usa. Cada vez que necesita construir un elemento, lo hace usando el constructor de copia , porque cada vez tiene algo que copiar: ya sea un elemento vectorial existente o un elemento que usted mismo suministró para copiar a través del parámetro de un método (explícita o implícitamente, confiando en un argumento predeterminado )

Puede escribir una clase así exactamente de la misma manera: cada vez que necesite construir un nuevo elemento en su matriz, solicite al usuario que le proporcione un elemento para copiar. En este caso, la construcción de ese elemento original se convierte en responsabilidad del usuario.

Cada vez que aparece como si std::vector "requiere" un constructor predeterminado de usted, simplemente significa que en algún lugar se basó en un argumento predeterminado de algunos de los métodos del vector , es decir, fue usted quien intentó construir un elemento por defecto no el vector El vector en sí, nuevamente, nunca intentará construir elementos por defecto.

Para evitar el requisito de constructor predeterminado durante la asignación de memoria, la biblioteca estándar asigna el bloque de memoria sin inicializar en bruto y luego inmediatamente copia y construye nuevos elementos en ese bloque de memoria sin procesar (que es algo new[] que no puede hacer). Esta funcionalidad está encapsulada en la clase std::allocator . También puede usar std::allocator en su código, lo que significa que la "magia" también está disponible para usted.

Nota: Lo anterior se aplica a la versión anterior a C ++ 11 de la especificación del lenguaje C ++. C ++ 11 cambió muchas cosas. Y estos cambios crean situaciones en las que std::vector puede usar constructores predeterminados internamente.

También podría valer la pena señalar que incluso la especificación C ++ 98 original permitió a las implementaciones utilizar la sobrecarga de funciones en lugar de los argumentos predeterminados para implementar la interfaz de biblioteca estándar. Esto significa que formalmente es posible tener una implementación válida de C ++ 98 de std::vector que usa constructores predeterminados internamente .


std::vector solo requiere que el elemento tenga un constructor predeterminado si lo usa de una manera que requiere el constructor predeterminado. Entonces este código (robado de una respuesta eliminada) no se compilará, porque X no tiene un ctor predeterminado:

#include <vector> struct X { X(int) {} }; int main(void) { std::vector<X> x(1); // vector of length 1, second argument defaults to X() !! return 0; }

Pero si escribes main como este en su lugar:

int main(void) { std::vector<X> x; // make empty vector x.push_back(X(1)); return 0; }

Entonces funciona bien.