Re: questions about dynamic binding
Gianni Mariani wrote:
On May 12, 11:03 pm, James Kanze <james.ka...@gmail.com> wrote:
On May 12, 12:13 pm, Jess <w...@hotmail.com> wrote:
...
The classical solution here is to provide a clone function in
the base class, i.e.:
class A
{
public:
A* clone() const
{
A* result = doClone() ;
assert( typeid( *result ) == typeid( *this ) ) ;
return result ;
}
private:
virtual A* doClone() const
// Except that usually, this will be pure virtual.
// It's fairly rare to have virtual functions in a
// base class which aren't pure virtual.
{
return new A( *this ) ;
}
} ;
class B
{
private:
virtual A* doClone() const
{
return new B( *this ) ;
}
If it was not a private method, it may be useful to define clone
methods to return the actual type they create. The compiler handles
upcasting for you if it is called from a base class. This is called a
co-variant return.
virtual B* doClone() const
{
return new B( *this ) ;
}
I know that the possibility exists, but I have my doubts with
regards to the utility. If for some reason, the interface
specification of B includes this extension, it is relatively
easy to add another public function along the lines of that in
A. With, of course, the same post-condition.
(In practice, I'm not sure just how important the verification
of the post condition is in this case. In the vast majority of
the cases, the virtual clone function can---and in fact
must---be pure in the base class, and there is only one level of
inheritance, so the compiler will not allow you to instantiate a
class which forgets it. And even in the other cases, it's the
sort of thing that tends to be spotted immediately in code
review. But the technique of using a non-virtual public
function to verify pre- and post-conditions and invariants is
generally useful, and worth knowing and practicing.)
--
James Kanze (Gabi Software) email: james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34