Fui a una entrevista de trabajo hoy y me hicieron esta interesante pregunta.
Además de la pérdida de memoria y el hecho de que no existe un dtor virtual, ¿por qué falla este código?
#include <iostream>
//besides the obvious mem leak, why does this code crash?
class Shape
{
public:
virtual void draw() const = 0;
};
class Circle : public Shape
{
public:
virtual void draw() const { }
int radius;
};
class Rectangle : public Shape
{
public:
virtual void draw() const { }
int height;
int width;
};
int main()
{
Shape * shapes = new Rectangle[10];
for (int i = 0; i < 10; ++i)
shapes[i].draw();
}
Shape **
apuntando a una matriz de rectángulos. Entonces el acceso debería haber sido formas [i] -> dibujar ();->
fue un error cometido por un editor.Respuestas:
No se puede indexar así. Ha asignado una matriz de
Rectangles
y almacenado un puntero al primero enshapes
. Cuando lo haceshapes[1]
, está desreferenciando(shapes + 1)
. Esto no le dará un puntero al siguienteRectangle
, sino un puntero a lo que sería el siguienteShape
en una supuesta matriz deShape
. Por supuesto, este es un comportamiento indefinido. En tu caso, estás teniendo suerte y tienes un accidente.El uso de un puntero
Rectangle
hace que la indexación funcione correctamente.Si desea tener diferentes tipos de
Shape
s en la matriz y usarlos polimórficamente, necesita una matriz de punteros a Shape.fuente
Como dijo Martinho Fernandes, la indexación está mal. Si, en cambio, quisiera almacenar una matriz de formas, tendría que hacerlo utilizando una matriz de formas *, así:
Tenga en cuenta que debe realizar un paso adicional para inicializar el rectángulo, ya que al inicializar la matriz solo se configuran los punteros y no los objetos en sí.
fuente
Al indexar un puntero, el compilador agregará la cantidad adecuada según el tamaño de lo que se encuentra dentro de la matriz. Entonces, digamos que sizeof (Shape) = 4 (ya que no tiene variables miembro). Pero sizeof (Rectángulo) = 12 (es probable que los números exactos sean incorrectos).
Entonces, cuando indexa comenzando en digamos ... 0x0 para el primer elemento, cuando intenta acceder al décimo elemento, está tratando de ir a una dirección no válida o una ubicación que no es el comienzo del objeto.
fuente