Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Help please: copying objects in C++

6 views
Skip to first unread message

Gerry Wolff

unread,
Apr 28, 1998, 3:00:00 AM4/28/98
to

I would be glad if someone could explain one aspect of C++ which
is puzzling me:

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

ge...@sees.bangor.ac.uk


Paul Derbyshire

unread,
Apr 29, 1998, 3:00:00 AM4/29/98
to Gerry Wolff

Gerry Wolff wrote:
>
> I would be glad if someone could explain one aspect of C++ which
> is puzzling me:
>
> 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!).

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|

Paul Derbyshire

unread,
Apr 29, 1998, 3:00:00 AM4/29/98
to

Paul Derbyshire wrote:
> Write a clone() method...

BTW, this is, as I recall, in the FAQ.

David Harmon

unread,
Apr 29, 1998, 3:00:00 AM4/29/98
to

On 28 Apr 1998 15:12:10 GMT, ge...@sees.bangor.ac.uk (Gerry Wolff)
wrote:

>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

Thomas Helvey

unread,
Apr 29, 1998, 3:00:00 AM4/29/98
to

In article <35469A12...@usa.net>, pder...@usa.net says...

>
>and override it in subclasses like so:
>
>class Q : public A {
> ...
> A *clone (void) { Q *result=new Q(*this); return result; }
> ...
>}
>
You really don't need the temp, and clone should be virtual and const. :)

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


Paul Derbyshire

unread,
Apr 29, 1998, 3:00:00 AM4/29/98
to

Thomas Helvey wrote:

> > 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...

0 new messages