views:

229

answers:

5

I have to do this for a basic C++ lecture at my university, so just to be clear: i would have used the STL if i was allowed to.

The Problem: I have a class named "shape3d" from which i derived the classes "cube" and "sphere". Now i have to implement "shape3d_stack", which is meant be able of holding objects of the types "cube" and "sphere". I used arrays for this and it worked quite well when i tried to do so with a stack of ints. I tried to do it like so:

shape3d_stack.cpp:

15    // more stuff
16    
17        shape3d_stack::shape3d_stack (unsigned size) :
18         array_ (NULL),
19         count_ (0),
20         size_  (size)
21        { array_ = new shape3d[size]; }
22    
23    // more stuff

but, unfortunately, the compiler tells me:

g++ -Wall -O2 -pedantic -I../../UnitTest++/src/ -c shape3d_stack.cpp -o shape3d_stack.o
shape3d_stack.cpp: In constructor ‘shape3d_stack::shape3d_stack(unsigned int)’:
shape3d_stack.cpp:21: error: cannot allocate an object of abstract type ‘shape3d’
shape3d.hpp:10: note:   because the following virtual functions are pure within ‘shape3d’:
shape3d.hpp:16: note:  virtual double shape3d::area() const
shape3d.hpp:17: note:  virtual double shape3d::volume() const

i guess this must be some kind of really ugly design error caused by myself. so how would be the correct way of using all kinds of objects derived from "shape3d" with my stack?

+7  A: 

You can't create objects from abstract classes.
You'll probably want to create an array of pointers to the abstract class, which is allowed, and fill them with derived instances:

// declaration somewhere:
shape3d** array_;

// initalization later:
array_ = new shape3d*[size];

// fill later, triangle is derived from shape3d:
array_[0] = new triangle;
Georg Fritzsche
+3  A: 

The line

array_ = new shape3d[size];

allocates an array of shape3d objects. Not cubes, not spheres, just plain old shape3d. But it's not possible to create even one shape3d object, as it is abstract.

In general, to use polymorphism and virtual functions, you need to use indirection: pointers and/or references, not literal objects. A shape3d* might point to a cube or to a sphere, but a shape3d is always a shape3d, not a subclass of shape3d.

David Seiler
A: 

Since shape3d is an abstract base class, you probably want your stack to store pointers to shape3d, rather than actual objects.

coppro
A: 

You cannot create a new array of the abstract class. What you can do is declare it as an array of pointers and then later on when you know which type of shape it is you can allocate the objects of the derived class of your choice.

A: 

Instead of a stack of objects, you need to create a stack of pointers to objects.

Jerry Coffin