On Apr 9, 7:04 am, Craig Scott
> On Apr 8, 5:22 pm, "Christopher Pisz"
>
>
>
> > "Marcel M=FCller"
>
> >news:47f9d24b$0$627$9b4e6d93@newsspool1.arcor-online.net...
>
> > > Christopher Pisz schrieb:
> > >> Not really. A Clone method is most likely some programmer's obsession=
> > >> with Java coming out in their C++ code. There is really no sense havi=
ng a
> > >> clone method in C++. We overload operator =3D or provide a copy
> > >> constructor.
>
> > > I do not agree to the last statement. In polymorphic classes there may=
be
> > > a need to invoke the copy constructor in abstact base classes. And sin=
ce
> > > the C++ language does not provide a direct way to do this (most other =
OO
> > > languages too), a virtual clone method is a common work-around.
>
> > > Marcel
>
> > Yea, I've seen that too. I think its a bunch of ick. Requiring the Abstr=
act
> > class to know the definition of a derived classes, creating a circular
> > dependancy. I've also seen people implementing a derived class code
> > identifier in all the classes in order for the abstract class to tell "w=
hat
> > kind am I cloning". There are better solutions IMO.
>
> Why must the abstract base class know the definition of a derived
> class? Because the C++ standard allows for covariant return types, the
> base class can be made completely oblivious to what subclasses are
> defined (that's the whole point). For example:
>
> class Base
> {
> public:
> // Constructor and other functions omitted for clarity
> virtual Base* clone() const =3D 0;
>
> };
>
> class Derived : public Base
> {
> public:
> // Constructor and other functions omitted for clarity
> virtual Derived* clone() const;
>
> };
>
> Note that the return type for the clone() function in Derived is
> Derived*, not Base* as declared in the base class.
Hmmm.... reading back over my post, I realized I neglected to explain
or show an example why the covariant return type is useful. I presumed
(perhaps incorrectly) by your comment that you needed somehow to get a
pointer to the derived class back from the clone() function rather
than a pointer to the base class. This was the need I was addressing
by the covariant return type feature. A bit of code using my Base/
Derived examples might make this clearer.
Derived d;
Base* bp =3D &d;
// Create a clone from the base class pointer.
// We get a Base* back, not a Derived*
Base* dClonedFromBase =3D bp->clone();
// Create a clone from the derived class.
// This time, we get a Derived* so we have
// the ability to call Derived member functions
// access its data members, etc.
Derived* dClonedFromDerived =3D d.clone();
In both cases, we get a full clone of the derived class, even though
cloning from the Base* pointer returns a Base* whereas cloning from a
Derived object gives us a Derived*. This feature allows you to use the
one function (clone() in this case) but still return the actual type
being cloned. In your client code, this means that whatever type you
are cloning from, you will have access to all member functions and
other member data of that type, not just the base class type. A bit
wordy, but I hope it's clear enough to get my point.
--
Computational Modeling, CSIRO (CMIS)
Melbourne, Australia