views:

82

answers:

3

I've not used C++ in a while, and I've become far too comfortable with the ease-of-use of real languages.

At any rate, I'm attempting to implement the Command pattern, and I need to map a number of command object implementations to string keys. I have an STL map of string to Command, and I'd like to copy the Command.

Essentially,

Command * copiedCommand = new Command( commandImplementation );

And I'd like to retain the functionality of commandImplementation. Since Command has the pure virtual function execute, this doesn't work. What's the correct way to do this?

A: 

If Command is an abstract class, you won't be able to call the copy constructor directly. Instead, you might consider creating a clone() method that returns a deep copy of the object. This could also be a pure-virtual method that returns your base class, such as:

class Command {
    public:
        virtual Command* clone(void) const = 0;
};
jheddings
+4  A: 

One way to do it would be to have add this to your Command class:

public:
   virtual Command * Clone() const = 0;

... and then in the various subclasses of Command, implement Clone() to return a copy of the object:

public:
   virtual Command * Clone() const {return new MyCommandSubclass(*this);}

Once that's done, you can then do what you want like this:

Command * copiedCommand = commandImplementation->Clone();
Jeremy Friesner
I bet Go makes this more elegant.
Stefan Kendall
YEs this would be a good answer for Java.
Martin York
A: 

http://en.wikipedia.org/wiki/Prototype_pattern

A prototype pattern is a creational design pattern used in software development when the type of objects to create is determined by a prototypical instance, which is cloned to produce new objects. This pattern is used to:

  • avoid subclasses of an object creator in the client application, like the abstract factory pattern does.
  • avoid the inherent cost of creating a new object in the standard way (e.g., using the 'new' keyword) when it is prohibitively expensive for a given application.

To implement the pattern, declare an abstract base class that specifies a pure virtual clone() method. Any class that needs a "polymorphic constructor" capability derives itself from the abstract base class, and implements the clone() operation.

The client, instead of writing code that invokes the "new" operator on a hard-coded class name, calls the clone() method on the prototype, calls a factory method with a parameter designating the particular concrete derived class desired, or invokes the clone() method through some mechanism provided by another design pattern.

Aurélien Vallée