views:

142

answers:

6

In other words, given a base class shape and a derived class rectangle:

class shape
{
public:
  enum shapeType {LINE, RECTANGLE};
  shape(shapeType type);
  shape(const shape &shp);
}

class rectangle : public shape
{
public:
  rectangle();
  rectangle(const rectangle &rec);
}

I'd like to know if I could create an instance of rectangle by calling:

shape *pRectangle = new shape(RECTANGLE);

and how could I implement the copy constructor, in order to get a new rectangle by calling:

shape *pNewRectangle = new shape(pRectangle);
+4  A: 

Short Answer: No

Long Answer:

You need a factory object/method.
You can add a static factory method to the base class the creates the appropriate object type.

class Shape
{
    static Shape* createShape(shapeType type)
    {
        switch (type)
        {
             case RECTANGLE:return new rectangle();
           ...
        }
    }
 };

Personal preference:

I would go with a completely different class to be the factory rather than using a static method on the base class. The reason for this is that every time you create a new Shape class the above style forces you to re-build the Shape class each time.

So I would separator out the factory into a ShapeFactory class.

Martin York
Why a class? I would simply make a factory function.
Nemanja Trifunovic
that's it, then.And according to this question - http://stackoverflow.com/questions/1021626/c-could-polymorphic-copy-constructors-work - I guess I also have to use a Clone method instead of the copy constructor.
djeidot
In the trivialist of cases a factory function is fine. But when things get more complex and you need to split the factory call into a couple of function calls the accesability constraints are a lot easier to handle then having multiple static functions. But in this case it is just a matter of style.
Martin York
When things a re more complex, if you have a class you can start using abstract factories and thus return different types of object depending on runtime configuration. So I could have a WindowShape factory and MacShapeFactory based of a simple abstract base factory. Again you can do this with functions but it just is never quite as neat.
Martin York
Cloning is so Java like. It just makes me shiver.
Martin York
A: 

Calling a constructor will always give you an object of the type of the constructor.

new shape(...)

I think you want to use the factory design pattern instead, where there is a static method on shape that can create any subtype, as necessary.

Michael Donohue
A: 
shape *pRectangle = new shape(RECTANGLE);

There is no way for you to create a derived class by constructing a base object. You have to do a new of the derived class itself.

Naveen
+1  A: 

You can't do this directly from within the constructor. Instead, you'll need to use another approach, such as a Factory method.

The problem is, when you do new shape(...), you'll always return an instance of shape - not rectangle. If you want a "rectangle", at some point, it will need to call new rectangle(..). A method could handle this logic for you, but not the default construction in C++.

Reed Copsey
A: 

In C++ you can use dynamic casting to accomplish this, but erm, no, not from within the constructor. Use it as implied above in a factory method

see e.g http://www.cprogramming.com/reference/typecasting/dynamiccast.html

David Archer
A: 

You can do something like that with Policy-Based design. Your code would be something like

shape* pRectangle = new derrivedType<rectangle>();

Policy-Based Design

Chad Simpkins