Cloning revisited

A

Alf P. Steinbach

Now that most (all?) common compilers support covariant routines it has become
much simpler to avoid the tedious manual implementation of cloning in each class.

Here's my take:


<code>
#include <memory>
#include <typeinfo>
#include <assert.h>

#define IMPLEMENT_CLONING( Class ) \
virtual Class* virtualClone() const \
{ \
assert( typeid( *this ) == typeid( Class ) ); \
return new Class( *this ); \
} \
\
std::auto_ptr<Class> clone() const \
{ \
return std::auto_ptr<Class>( virtualClone() ); \
}
</code>


The 'virtualClone' is not mean to be used directly, and I considered whether to
make it difficult to use it directly. But this is perhaps a case where the FAQ's
advice that a stern comment about not doing something often suffices, is spot
on? Anyway, after first trying a scheme of inheriting cloning via templated
classes, based on dominance in an inheritance chain from a topmost virtual base
class (it got ugly, three compilers reported three very different reasons why
they couldn't accept it, and I can't even find a word about dominance in the
Holy Standard!), I finally followed the KISS principle: Keep It Simple, Stupid!


Cheers,

- Alf
 
J

Joshua Maurice

Now that most (all?) common compilers support covariant routines it has become
much simpler to avoid the tedious manual implementation of cloning in each class.

Here's my take:

<code>
#include    <memory>
#include    <typeinfo>
#include    <assert.h>

#define IMPLEMENT_CLONING( Class )                                  \
     virtual Class* virtualClone() const                             \
     {                                                               \
         assert( typeid( *this ) == typeid( Class ) );               \
         return new Class( *this );                                  \
     }                                                               \
                                                                     \
     std::auto_ptr<Class> clone() const                              \
     {                                                               \
         return std::auto_ptr<Class>( virtualClone() );              \
     }
</code>

The 'virtualClone' is not mean to be used directly, and I considered whether to
make it difficult to use it directly. But this is perhaps a case where the FAQ's
advice that a stern comment about not doing something often suffices, is spot
on? Anyway, after first trying a scheme of inheriting cloning via templated
classes, based on dominance in an inheritance chain from a topmost virtual base
class (it got ugly, three compilers reported three very different reasons why
they couldn't accept it, and I can't even find a word about dominance in the
Holy Standard!), I finally followed the KISS principle: Keep It Simple, Stupid!

Last I checked, visual studios doesn't support covariant return types
with virtual inheritance and/or multiple inheritance. Testing with VS
2008, aka v9.

struct A { virtual A* foo() { return 0; } };
struct B : A { virtual B* foo() { return 0; } };
struct C : A { virtual C* foo() { return 0; } };

//this line
struct D : B, C { virtual D* foo() { return 0; }};
//gives error
1>c:\documents and settings\jmaurice\desktop\cpp_tester\new_streams.cpp
(657) : error C2555: 'D::foo': overriding virtual function return type
differs and is not covariant from 'B::foo'
1> c:\documents and settings\jmaurice\desktop\cpp_tester
\new_streams.cpp(655) : see declaration of 'B::foo'
1> 'A' : ambiguous base is not covariant
1>c:\documents and settings\jmaurice\desktop\cpp_tester\new_streams.cpp
(657) : error C2555: 'D::foo': overriding virtual function return type
differs and is not covariant from 'C::foo'
1> c:\documents and settings\jmaurice\desktop\cpp_tester
\new_streams.cpp(656) : see declaration of 'C::foo'
1> 'A' : ambiguous base is not covariant
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,123
Latest member
Layne6498
Top