I want to copy a list of objects with various classes but it is
not clear to me what copy constructor to use. Processing a list
of objects of various classes normally allows one to use
overloading of the relevant method. But this is not possible
with copying because the copy constructor for each class has a
different name. It is no good using the copy constructor for the
base class for all the objects because that simply means you get
objects containing only the fields in the base class (I have
tested it!).
Please send me an e-mail if you can answer this question.
With thanks,
Gerry Wolff
Write a clone() method: say you derived all these from the class A, you'd have
the clone method like this:
class A {
...
virtual A *clone (void) { ... }
...
}
and override it in subclasses like so:
class Q : public A {
...
A *clone (void) { Q *result=new Q(*this); return result; }
...
}
As you can see it is a dispatcher for the appropriate copy constructor. It uses
the Q copy constructor, not that of A, and returns an A * pointing to a Q. With
proper use of virtual methods, the pointer being an A * and not a Q * will not
be a problem.
--
.*. "Clouds are not spheres, mountains are not cones, coastlines are not
-() < circles, and bark is not smooth, nor does lightning travel in a
`*' straight line." -------------------------------------------------
-- B. Mandelbrot |http://www3.sympatico.ca/bob.beland/indexn2f.html
_____________________ ____|________ Paul Derbyshire pder...@usa.net
Programmer & Humanist|ICQ: 10423848|
BTW, this is, as I recall, in the FAQ.
>I want to copy a list of objects with various classes but it is
>not clear to me what copy constructor to use. Processing a list
>of objects of various classes normally allows one to use
>overloading of the relevant method. But this is not possible
>with copying because the copy constructor for each class has a
>different name.
A typical solution is to use a virtual base*clone() method in each
subclass that constructs a copy of itself using new.
>Please send me an e-mail if you can answer this question.
Try soc.penpals
class Q : public A {
...
virtual A* clone() const { return new Q(*this); }
...
};
This has a problem in that you have to to use pointers if you want to
put these objects in a container.
One solution would be to use a handle class:
class A { ... }
class B : public A { ... }
class H
{
public:
H(int x) : rep(new A(x)) { }
H(int x, int y) : rep(new B(x, y)) { }
H(const H& r) : rep(r.rep->clone()) { }
H& operator=(const H& r)
{ if (r.rep != rep) { delete rep; rep = r.rep->clone; } return *this; }
f(int x) { return rep->f(x); }
private:
A* rep;
};
There are a lot of things you can do to make this better, it's just
an illustration of the concept.
There is a lot of good information on various ways to deal with
the problem in the literature. Check out Stroustrup, Koenig, Meyers,
Coplien, etc. they all address these issues in some detail in their
books.
Thomas
> > A *clone (void) { Q *result=new Q(*this); return result; }
> You really don't need the temp, and clone should be virtual and const. :)
I suppose it should be const, and again virtual if Q might be subclassed.
> virtual A* clone() const { return new Q(*this); }
> This has a problem in that you have to to use pointers if you want to
> put these objects in a container.
Pointers can be annoying at times.
> One solution would be to use a handle class:
>
> class A { ... }
> class B : public A { ... }
>
> class H
> {
> public:
> H(int x) : rep(new A(x)) { }
> H(int x, int y) : rep(new B(x, y)) { }
> H(const H& r) : rep(r.rep->clone()) { }
> H& operator=(const H& r)
> { if (r.rep != rep) { delete rep; rep = r.rep->clone; } return *this; }
> f(int x) { return rep->f(x); }
> private:
> A* rep;
> };
There should be a () after that clone :-)
Also, this seems designed around a fixed (known beforehand) inheritance
hierarchy...
> There are a lot of things you can do to make this better, it's just
> an illustration of the concept.
> There is a lot of good information on various ways to deal with
> the problem in the literature. Check out Stroustrup, Koenig, Meyers,
> Coplien, etc. they all address these issues in some detail in their
> books.
>
> Thomas
Thanks for the references...