2

I am reading some clone c++ implementation, it seems always define as

Clonable* clone();

I am wondering why always return a pointer; can I define a clone to return a Clonable object?

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
Adam Lee
  • 24,710
  • 51
  • 156
  • 236
  • 1
    Not seeing context is rough, but my crystal ball tells me `Clonable` is an interface in a virtual hierarchy. [An instance would **slice**.](http://stackoverflow.com/questions/274626/what-is-object-slicing) – WhozCraig Jan 16 '15 at 04:14
  • 1
    It's worth noting that a decent *modern* implementation of the cloneable pattern would return an `std::unique_ptr` instead of a raw pointer. – cdhowie Jan 16 '15 at 06:01
  • @cdhowie: not so easily with covariant return type :( ... – Jarod42 Jan 16 '15 at 09:00
  • @Jarod42 Sure it is... why wouldn't it be? – cdhowie Jan 17 '15 at 01:27
  • @cdhowie: I meant that `std::unique_ptr clone() const override` is not possible :(. You have to make trade off: `std::unique_ptr clone() const override` or `Derived* clone() const override`. – Jarod42 Jan 19 '15 at 09:56
  • @Jarod42 Sure. The way I typically implement this is to have a protected `virtual std::unique_ptr clone_impl() const` and a public `std::unique_ptr clone() const` on derived types that calls the protected method and returns a downcast pointer. It's not super-duper easy but any reasonably competent C++ developer can implement it pretty easily. – cdhowie Jan 19 '15 at 19:02

1 Answers1

8

can I define a clone to return a Clonable object?

Sure. Heck, you could make a clone() method that returns anything you want. My guess is that the Clonable class is meant to be used polymorphically, and that the clone() method is virtual. Pointers (or references) are your only option for runtime polymorphism in C++. If it didn't return a pointer, you'd get object slicing.

Community
  • 1
  • 1
Cornstalks
  • 37,137
  • 18
  • 79
  • 144
  • What about type casting? Does the client code need to be something like `auto widget = static_cast(dynamic_cast(original->clone()))`? –  Jan 16 '15 at 04:59
  • Without any casting, the user will just get a `Clonable*` back. Only one cast would be needed if you want the derived type, though. You shouldn't need to double-cast things like in that example. – Cornstalks Jan 16 '15 at 05:07