 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Joel Schaerer Guest
|
Posted: Sat Oct 11, 2003 3:10 pm Post subject: virtual copy constructor |
|
|
Hello all,
I have an ABC A which has several derived classes. At one point in my
program i have a pointer of type A*, and would like to create a copy
of the object it points to. My idea was to declare a virtual copy
constructor in A. However, g++ says "Constructors cannot be declared
virtual". Why is that so? What is the solution to my problem?
Many thanks,
js
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
WW Guest
|
Posted: Sun Oct 12, 2003 12:17 am Post subject: Re: virtual copy constructor |
|
|
Joel Schaerer wrote:
| Quote: | Hello all,
I have an ABC A which has several derived classes. At one point in my
program i have a pointer of type A*, and would like to create a copy
of the object it points to. My idea was to declare a virtual copy
constructor in A. However, g++ says "Constructors cannot be declared
virtual". Why is that so? What is the solution to my problem?
|
AFAIK today you need a virtual clone function and discipline, to make it
sure you override it in every subclass:
struct A {
// Assuming it is abstract:
virtual A*clone() const = 0;
private:
// private parts
// censored
};
struct B : A {
// This is a concrete class:
virtual B*clone() const {
return new (*this);
}
//...
};
struct C : B {
// This is easy to forget!
// since there will be no
// compiler error.
virtual C*clone() const {
return new (*this);
}
//...
};
The functions are shown in inline notation for saving space. In real life
there is not too much sense in making them inline: if you know the dynamic
type, you don't need to call them.
This cloning-problem shows one "missing" or "it would really be nice to
have" feature of C++: there is no way to tell that some function must be
overriden in every derived class.
--
WW aka Attila
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Sun Oct 12, 2003 12:42 am Post subject: Re: virtual copy constructor |
|
|
Joel Schaerer wrote:
| Quote: | I have an ABC A which has several derived classes. At one point in my
program i have a pointer of type A*, and would like to create a copy
of the object it points to. My idea was to declare a virtual copy
constructor in A.
|
The 'virtual copy constructor' is a name for a pattern. Usually, it is a
function called clone() which calls the private virtual do_clone().
do_clone() then just returns 'new Derived(*this)' for each derived
class.
| Quote: | However, g++ says "Constructors cannot be declared
virtual". Why is that so? What is the solution to my problem?
|
For something to be called polymorphically, you first need an object.
The
constructor on the other hand creates an object.
Uli
--
Questions ?
see C++-FAQ Lite: http://parashift.com/c++-faq-lite/ first !
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sun Oct 12, 2003 12:44 am Post subject: Re: virtual copy constructor |
|
|
In article <bm6e2l$v6h$1 (AT) trompette (DOT) imag.fr>, Joel Schaerer
<joel.schaerer (AT) inrialpes (DOT) fr> writes
| Quote: | Hello all,
I have an ABC A which has several derived classes. At one point in my
program i have a pointer of type A*, and would like to create a copy
of the object it points to. My idea was to declare a virtual copy
constructor in A. However, g++ says "Constructors cannot be declared
virtual". Why is that so? What is the solution to my problem?
Indeed there is no such thing as a virtual constructor in C++ however |
any respectable book on C++ beyond the novice stage will tell you how to
deal with this problem. One common solution is to use a virtual clone
function.
--
Francis Glassborow ACCU
If you are not using up-to-date virus protection you should not be
reading
this. Viruses do not just hurt the infected but the whole community.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Sun Oct 12, 2003 9:34 am Post subject: Re: virtual copy constructor |
|
|
WW wrote:
| Quote: |
This cloning-problem shows one "missing" or "it would really be nice to
have" feature of C++: there is no way to tell that some function must be
overriden in every derived class.
|
A better name would be an "I can design the derived class better than
its actual designer" feature. Why would you want to preclude an
implementation like this?
class Base
{
virtual Base *clone() const = 0;
};
class Intermediate : public Base
{
Intermediate *clone() const
{
Intermediate *x = x_clone();
// do something to x that's specific to this class
return x;
}
Intermediate *xclone() const = 0;
};
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Joshua Lehrer Guest
|
Posted: Sun Oct 12, 2003 9:37 am Post subject: Re: virtual copy constructor |
|
|
Joel Schaerer <joel.schaerer (AT) inrialpes (DOT) fr> wrote
| Quote: | Hello all,
I have an ABC A which has several derived classes. At one point in my
program i have a pointer of type A*, and would like to create a copy
of the object it points to. My idea was to declare a virtual copy
constructor in A. However, g++ says "Constructors cannot be declared
virtual". Why is that so? What is the solution to my problem?
Many thanks,
js
|
Because a virtual method is dispatched based on the dynamic type of
the object. In the case of a constructor, you have no object to
determine the dynamic type of!
Base *pBase = new Sub;
pBase->virtual_method();
the method is dispatched based on dynamic type of pBase which, in this
case, is Sub.
In the case of a copy constructor, you must specify the type:
Base *pBase2 = new ???(*pBase);
The solution should be "obvious". You do have a type with which you
can dynamically determine which "constructor" to call, "pBase". So,
change your code around a bit to be:
Base *pBase2 = pBase->clone();
make clone a purely virtual function on the base class, the subclasses
override it, and you get the functionality you were looking for.
pBase2 will be a "copy" of pBase, whatever that is:
struct Base {
virtual Base* clone() const = 0;
};
struct Sub {
virtual Sub* clone() const;
};
Notice that Sub::clone() returns a Sub* and Base::clone() returns a
Base*. This subclass is still an override of the baseclass- this is
called "covariant return types". It allows you to write this:
Sub *pSub2 = pSub->clone();
joshua lehrer
factset research systems
NYSE:FDS
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sun Oct 12, 2003 10:34 pm Post subject: Re: virtual copy constructor |
|
|
In article <3F88AB35.C612FBF6 (AT) acm (DOT) org>, Pete Becker <petebecker (AT) acm (DOT) org>
writes
| Quote: | WW wrote:
This cloning-problem shows one "missing" or "it would really be nice to
have" feature of C++: there is no way to tell that some function must be
overriden in every derived class.
A better name would be an "I can design the derived class better than
its actual designer" feature. Why would you want to preclude an
implementation like this?
class Base
{
virtual Base *clone() const = 0;
};
class Intermediate : public Base
{
Intermediate *clone() const
{
Intermediate *x = x_clone();
// do something to x that's specific to this class
return x;
}
Intermediate *xclone() const = 0;
};
The mechanism you are proposing we should use also determines how |
programmers should behave because it only works in the case that only
leaf classes are concrete.
This is, IMHO, much more restrictive. I think that both requiring that
the most derived class provide a final overrider and allowing public
inheritance of from concrete classes are perfectly reasonable. currently
the Standard allows the latter but provides no support for the former.
There are good reasons that C++ does not provide virtual ctors, but
allowing a mechanism whereby they can be safely faked is no more a
matter of allowing the base class designer to determine how derived
classes shall behave than that we already have with virtual dtors.
Actually in your philosophy, what is the purpose of a pure virtual? It
places a requirement on derived classes. Most of us consider that a fair
deal with the cost being worth the benefit.
--
Francis Glassborow ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
James Kanze Guest
|
Posted: Mon Oct 13, 2003 4:25 am Post subject: Re: virtual copy constructor |
|
|
Pete Becker <petebecker (AT) acm (DOT) org> writes:
| Quote: | WW wrote:
This cloning-problem shows one "missing" or "it would really be
nice to have" feature of C++: there is no way to tell that some
function must be overriden in every derived class.
A better name would be an "I can design the derived class better
than its actual designer" feature.
|
Encouraging the impossible is never a feature. No class hierarchy is
better than the poorest designed class in it.
On the other hand, it is easy enough to implement the check if he thinks
it important.
| Quote: | Why would you want to preclude an implementation like this?
class Base
{
virtual Base *clone() const = 0;
};
class Intermediate : public Base
{
Intermediate *clone() const
{
Intermediate *x = x_clone();
// do something to x that's specific to this class
return x;
}
Intermediate *xclone() const = 0;
};
|
But he doesn't want to preclude that. What he wants is to enforce that
for all classes D derived from Base, the dynamic type of *D::clone() is
D.
--
James Kanze mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France +33 1 41 89 80 93
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
rossum Guest
|
Posted: Mon Oct 13, 2003 4:26 am Post subject: Re: virtual copy constructor |
|
|
On 11 Oct 2003 11:10:25 -0400, Joel Schaerer
<joel.schaerer (AT) inrialpes (DOT) fr> wrote:
| Quote: | I have an ABC A which has several derived classes. At one point in my
program i have a pointer of type A*, and would like to create a copy
of the object it points to. My idea was to declare a virtual copy
constructor in A. However, g++ says "Constructors cannot be declared
virtual". Why is that so? What is the solution to my problem?
|
Bjarne says:
"A virtual call is a mechanism to get work done given partial
information. In particular, "virtual" allows us to call a function
knowing only an interfaces and not the exact type of the object. To
create an object you need complete information. In particular, you
need to know the exact type of what you want to create. Consequently,
a "call to a constructor" cannot be virtual."
See: http://www.research.att.com/~bs/bs_faq2.html#virtual-ctor
rossum
--
The Ultimate Truth is that there is no Ultimate Truth
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Mon Oct 13, 2003 4:30 am Post subject: Re: virtual copy constructor |
|
|
Francis Glassborow wrote:
| Quote: |
In article <3F88AB35.C612FBF6 (AT) acm (DOT) org>, Pete Becker
[email]petebecker (AT) acm (DOT) org[/email]
writes
WW wrote:
This cloning-problem shows one "missing" or "it would really be
nice to
have" feature of C++: there is no way to tell that some function
must be
overriden in every derived class.
A better name would be an "I can design the derived class better than
its actual designer" feature. Why would you want to preclude an
implementation like this?
class Base
{
virtual Base *clone() const = 0;
};
class Intermediate : public Base
{
Intermediate *clone() const
{
Intermediate *x = x_clone();
// do something to x that's specific to this class
return x;
}
Intermediate *xclone() const = 0;
};
The mechanism you are proposing we should use also determines how
programmers should behave because it only works in the case that only
leaf classes are concrete.
|
I'm not proposing that "we" use any mechanism. I gave an example that
illustrates a consequence of programmers presuming they know best how to
design classes they know nothing about.
You haven't answered the question I asked: Why would you want to
preclude an implementation like that?
| Quote: | Actually in your philosophy, what is the purpose of a pure virtual?
|
A pure virtual says that the class I'm writing doesn't define a complete
version of that function, and that I call it.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Siemel Naran Guest
|
Posted: Mon Oct 13, 2003 12:04 pm Post subject: Re: virtual copy constructor |
|
|
"Ulrich Eckhardt" <doomster (AT) knuut (DOT) de> wrote
| Quote: | Joel Schaerer wrote:
I have an ABC A which has several derived classes. At one point in my
program i have a pointer of type A*, and would like to create a copy
of the object it points to. My idea was to declare a virtual copy
constructor in A.
The 'virtual copy constructor' is a name for a pattern. Usually, it is a
function called clone() which calls the private virtual do_clone().
do_clone() then just returns 'new Derived(*this)' for each derived
class.
|
My clone() function returns a smart pointer, usually std::auto_ptr, so I
can't take advantage of covariant returns (but what good is it anyway?). It
is also inline and has an assert.
My private myclone() function returns a raw pointer, so users of the class
are required to read the documentation and override it for every class.
// class Definition (abstract)
// in concrete classes must override
// myclone (always)
// myfresh (always)
// doswap (if new data)
class Definition
{
public:
...
virtual ~Definition();
std::auto_ptr<Definition> clone() const;
std::auto_ptr<Definition> fresh() const;
void swap(Definition&);
...
protected: // pure virtual functions -- none are defined
...
virtual void doswap(Definition&) = 0; // defined, does nothing
private:
...
virtual Definition * myclone() const = 0; // not defined
virtual Definition * myfresh() const = 0; // not defined
};
inline
std::auto_ptr<Definition> Definition::clone() const
{
std::auto_ptr<Definition> out(myclone());
assert(typeid(*this)==typeid(*out));
return out;
}
inline
std::auto_ptr<Definition> Definition::fresh() const
{
std::auto_ptr<Definition> out(myfresh());
assert(typeid(*this)==typeid(*out));
return out;
}
inline
void Definition::swap(Definition& that)
{
assert(typeid(*this)==typeid(that));
doswap(that);
}
--
+++++++++++
Siemel Naran
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Attila Feher Guest
|
Posted: Mon Oct 13, 2003 12:06 pm Post subject: Re: virtual copy constructor |
|
|
James Kanze wrote:
| Quote: | Encouraging the impossible is never a feature. No class hierarchy is
better than the poorest designed class in it.
|
??? Me not get this. Why would I encourage the impossible?
| Quote: | On the other hand, it is easy enough to implement the check if he
thinks it important.
|
How?
| Quote: | But he doesn't want to preclude that. What he wants is to enforce
that for all classes D derived from Base, the dynamic type of
*D::clone() is D.
|
That too. How do you ensure that (compile time!) usign the existing
language?
--
Attila aka WW
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Mon Oct 13, 2003 8:49 pm Post subject: Re: virtual copy constructor |
|
|
In article <3F89EA41.9924D7B1 (AT) acm (DOT) org>, Pete Becker <petebecker (AT) acm (DOT) org>
writes
| Quote: | A pure virtual says that the class I'm writing doesn't define a complete
version of that function, and that I call it.
|
And the suggested extension is that a programmer should be allowed to
say 'there must be an implementation provided in the most derived
class.' The implementation of a clone() method is an existence proof
that such a requirement is useful.
--
Francis Glassborow ACCU
If you are not using up-to-date virus protection you should not be reading
this. Viruses do not just hurt the infected but the whole community.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Oct 14, 2003 8:45 pm Post subject: Re: virtual copy constructor |
|
|
"Attila Feher" <attila.feher (AT) lmf (DOT) ericsson.se> wrote
| Quote: | James Kanze wrote:
Encouraging the impossible is never a feature. No class hierarchy
is better than the poorest designed class in it.
??? Me not get this. Why would I encourage the impossible?
|
I wasn't responding to you. I was responding to a statement by Pete
Becker that "I can design the derived class better than its [the base
class'] actual designer". My response is simply that it is impossible.
If the base class designer has not foreseen the case, your derived class
cannot change that.
| Quote: | On the other hand, it is easy enough to implement the check if he
thinks it important.
How?
But he doesn't want to preclude that. What he wants is to enforce
that for all classes D derived from Base, the dynamic type of
*D::clone() is D.
That too. How do you ensure that (compile time!) usign the existing
language?
|
Not compile time, but it is easy to implement in run-time. And since
you certainly aren't going to release software without having tested all
of the functions in all of the classes, you'll discover the problem.
That doesn't mean that I'm against any proposal that would provide a
compile time check. Quite the contrary -- I think that it is the sort
of error that can easily occur, and while it is also the sort of error
which generally gets caught in code review, a compiler check would be
better. But I haven't seen any proposed syntax, to date, so I can't say
whether it would be worth it or not.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Pete Becker Guest
|
Posted: Tue Oct 14, 2003 9:11 pm Post subject: Re: virtual copy constructor |
|
|
James Kanze wrote:
| Quote: |
But he doesn't want to preclude that. What he wants is to enforce that
for all classes D derived from Base, the dynamic type of *D::clone() is
D.
|
The comment that I replied to was: "there is no way to tell that some
function must be overriden in every derived class." That is, he wants to
write something in Base that requires every class derived from
Intermediate to implement clone.
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|