Q: How to copy a polymorphic class?

S

Simon Elliott

--- foo.h ---
class foo
{
public:
virtual void DoStuff(void);
virtual ~foo();
};

--- bar.h ---
#include "foo.h"
class bar:public foo
{
public:
virtual void DoStuff(void);
};

--- bloggs.cpp ---

#include "foo.h"
extern void Bloggs(foo* myFoo)
{
foo* localFoo = new foo(*myFoo);
localFoo->DoStuff();
delete localFoo;
}

--- main.cpp ---
#include "bar.h"
#include "bloggs.h"
int main(int argc, char* argv[])
{
bar myBar;
Bloggs (&myBar);
return 0;
}

In the code above, In the function "Bloggs", localFoo is a foo copy
constructed from the foo part of the bar argument I passed in.

Instead of this, I want to copy the complete bar argument and assign the
result to localFoo. Is there any way of doing this without bloggs.cpp
needing to #include "bar.h"? (I suppose I need something analogous to a
virtual copy constructor...)
 
S

Simon Elliott

Rolf Magnus said:
Of course every derived class would need that function, and it would
need to be virtual or pure virtual in the base class, and it should be
const. Also, clone() is a more widely used (and more appropriate) name
for it.

I'll make it pure virtual in the base class. This will make sure no-one
can put together a derived class without this method!
 
L

lilburne

Simon said:
Excellent. That will do the job nicely.

Sorry the type returned should be that of the base class,
shouldn't type code when the cat is clawing at your leg for
food:

Base* Derived::create_new() const;
 
D

Davlet Panech

Rolf Magnus said:
Of course every derived class would need that function, and it would
need to be virtual or pure virtual in the base class, and it should be
const. Also, clone() is a more widely used (and more appropriate) name
for it.


Also, it should return a "Base *", not "Derived *".
 
P

Peter van Merkerk

Of course every derived class would need that function, and it would
Also, it should return a "Base *", not "Derived *".

No, it doesn't have to unless your compiler chokes on it. Returning "Derived
*" is legal as far as the C++ standard is concerned. See also chapter 15.6.2
of the book "The C++ Programming Language" from Bjarne Stroustrup.
 
P

Peter van Merkerk

Derived* Derived::create_new()
Sorry the type returned should be that of the base class,
shouldn't type code when the cat is clawing at your leg for
food:

Base* Derived::create_new() const;

Actually the original example you provided is correct as far as the C++
standard (section 10.3) is concerned. The only problem with it is that some
C++ compilers (including some very popular ones) do not support covariant
return types. If the compiler doesn't accept covariant return types,
returning Base* instead should work fine.
 
L

lilburne

Peter said:
Actually the original example you provided is correct as far as the C++
standard (section 10.3) is concerned. The only problem with it is that some
C++ compilers (including some very popular ones) do not support covariant
return types. If the compiler doesn't accept covariant return types,
returning Base* instead should work fine.

Unfortunately that is the case. When need to compile on
three different platforms so tend to take the line of least
resistence.
 
S

Simon Elliott

Peter van Merkerk said:
No, it doesn't have to unless your compiler chokes on it. Returning "Derived
*" is legal as far as the C++ standard is concerned. See also chapter 15.6.2
of the book "The C++ Programming Language" from Bjarne Stroustrup.

FWIW, I tested the example code with Borland C++ Builder 6.0 c/w patch
4, and "derived*" worked fine.
 
P

Peter van Merkerk

Derived* Derived::create_new()
Unfortunately that is the case. When need to compile on
three different platforms so tend to take the line of least
resistence.

Writing code that should compile on three different compilers, two of
which are extremely non-compilant, and the other reasonably compiliant
(but nowhere near being able compile something like Loki) ... I
understand what you mean.... :-(
 
S

stelios xanthakis

Simon Elliott said:
FWIW, I tested the example code with Borland C++ Builder 6.0 c/w patch
4, and "derived*" worked fine.

In simple inheritance &Base==&derrived so most compilers silently
pretend to implement this. If the inheritance is virtual or base
comes from multiple inheritance, the compiler may say "covariant
return types not implemented".

I don't see much meaning in using a covariant return type in
this case. Even if you return Base or Derrived it's the same
thing (the compiler will downcast before or after returning).
Covariants are interesting in the case you know what you're
expecting, and in this case virtual does not make much sense.
My point is: covariant returns is no killer-feature.

Unless of course I missed something (?)

Stelios.
http://students.ceid.upatras.gr/~sxanth/lwc/index.html
[the regular expressions are coming]
 
R

Rolf Magnus

lilburne said:
Yes:

Derived* Derived::create_new()
{
return new Derived(*this);
}

Of course every derived class would need that function, and it would
need to be virtual or pure virtual in the base class, and it should be
const. Also, clone() is a more widely used (and more appropriate) name
for it.
 

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,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top