Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can a pointer to base point to an array of derived objects?

Tags:

c++

pointers

I went to a job interview today and was given this interesting question.

Besides the memory leak and the fact there is no virtual dtor, why does this code crash?

#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(); } 
like image 254
Tony The Lion Avatar asked Aug 25 '11 19:08

Tony The Lion


People also ask

Can a pointer to a base class can point to objects of a derived class?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.

Can a base class pointer contain reference of its derived class?

// As base-class pointer cannot access the derived class variable.

Can pointer to derived class be created?

A Base Class pointer can point to a derived class object.

Can a pointer point to an array C++?

In C++, Pointers are variables that hold addresses of other variables. Not only can a pointer store the address of a single variable, it can also store the address of cells of an array.


2 Answers

You cannot index like that. You have allocated an array of Rectangles and stored a pointer to the first in shapes. When you do shapes[1] you're dereferencing (shapes + 1). This will not give you a pointer to the next Rectangle, but a pointer to what would be the next Shape in a presumed array of Shape. Of course, this is undefined behaviour. In your case, you're being lucky and getting a crash.

Using a pointer to Rectangle makes the indexing work correctly.

int main() {    Rectangle * shapes = new Rectangle[10];    for (int i = 0; i < 10; ++i) shapes[i].draw(); } 

If you want to have different kinds of Shapes in the array and use them polymorphically you need an array of pointers to Shape.

like image 141
R. Martinho Fernandes Avatar answered Oct 12 '22 23:10

R. Martinho Fernandes


As Martinho Fernandes said, the indexing is wrong. If you wanted instead to store an array of Shapes, you would have to do so using an array of Shape *'s, like so:

int main() {    Shape ** shapes = new Shape*[10];    for (int i = 0; i < 10; ++i) shapes[i] = new Rectangle;    for (int i = 0; i < 10; ++i) shapes[i]->draw(); } 

Note that you have to do an extra step of initializing the Rectangle, since initializing the array only sets up the pointers, and not the objects themselves.

like image 30
Patrick Costello Avatar answered Oct 12 '22 23:10

Patrick Costello