Question

I am learning C++ in class and am working on trying to return a pointer to a derived object using a virtual create/clone function.

I found this implementation and am about to build around it http://www.cs.uregina.ca/Links/class-info/210/C++FAQ/virtual-functions.html#[20.5]

What I don't understand is how does the pointer returned actually point to any relevant data after clone() or create() exit their block?

Is there a better approach to this or is this where I need to program a function per case?

Thanks much

class Shape {
 public:
   virtual ~Shape() { }                 // A virtual destructor
   virtual void draw() = 0;             // A pure virtual function
   virtual void move() = 0;
   // ...
   virtual Shape* clone()  const = 0;   // Uses the copy constructor
   virtual Shape* create() const = 0;   // Uses the default constructor
 };

 class Circle : public Shape {
 public:
   Circle* clone()  const { return new Circle(*this); }
   Circle* create() const { return new Circle();      }
   // ...
 };
Was it helpful?

Solution

...how does the pointer returned actually point to any relevant data after clone() or create() exit their block?

Operator new allocates memory dynamically. That memory is valid until it is free'd using delete. Neither clone() or create() “deletes” those pointers and so both of those functions return a valid pointer.

Is there a better approach to this or is this where I need to program a function per case?

Since polymorphism is used here, the assumption is that users work with Shape class and are not aware of the actual implementation of those objects (i.e. they only work with “interface”). Without knowing what the actual implementation is, it becomes impossible to neither create nor copy the object.

The only place where the type is known is inside methods of the class that implement the interface (which in your case is Circle). So that is the only place where you basically know the type, its size, and all other necessary information needed to create and/or copy the object. So the answer is basically yes, you have to implement both create() and clone() for each top-level class that inherits Shape. Otherwise it would be either impossible to create/clone the object, or even worse - you may run into an object slicing problem.

Is creating a static object a viable workaround or does that negate all work to be OO?

I don't see how creating a static object helps here. Static objects usually exists one instance per scope. The whole purpose of having create() and clone() is to be able to create multiple instances of the object (either default or or a a copy of one of existing instances). So having a single static instance will not help to implement what the code is supposed to be doing.

OTHER TIPS

Clone() used exactly like that is usual. Create() is not really. Can you show a use case when you'd use that through virtual dispatch?

What I did use frequently, was static member Create(). That played as factory method. Every class got registered in a map with some ID and pointer to this Create function. Then could be used to create proper objects knowing just the ID (say read from file), and then call virtual functions on the new instance (i.e. to deserialize the content from the file).

To avoid copy-paste I used a macro to declare and implement all the mandatory functions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top