Template overriding base class virtual function?

P

Peter Davis

I'm trying to write something like a clone() method using the curiously
recurring template pattern. What I'm doing is similar to what's
described here:

http://nerdland.net/2009/06/covariant-templatized-virtual-copy-constructors/

but simpler, since I'm not worried about covariance. My clone() method
will always return a Base*. So I have something like

class Base
{
Base(){}
Base(const Base& other){}
virtual Base* clone(){Base b = new Base(); return b;}
};

// This template defines a clone() method with the same signature
// as the one in Base.
template <typename D> class Cloneable
{
public:
virtual Base* clone() {Base b = new D(this); return b;}
};

// I think by inheriting from Cloneable, the clone() method in
// Cloneable() should override the one in Base. But it doesn't.
class Derived : public Base, public Cloneable<Derived>
{
Derived() : Base() {}
Derived(const Derived& other) : Base(other) {}
}

When built with Visual Studio 2008, at least, the debugger shows me that
it's the Base::clone() function that always gets called, instead of the
one derived from Cloneable.

If I make both Base and Cloneable be virtual base classes, this works,
but I don't understand why this is necessary. Why doesn't the template
just override the Base definition of clone()?

Thanks!
-pd
 
C

Casey

If I make both Base and Cloneable be virtual base classes, this works,
but I don't understand why this is necessary. Why doesn't the template
just override the Base definition of clone()?

Because "the template" (Cloneable<Derived>) doesn't derive from Base. Try:


class Base
{
public:
virtual Base* clone() const = 0;
};

template <typename D> class Cloneable : public Base
{
public:
virtual Base* clone() const {
return new D(*static_cast<const D*>(this));
}
};

class Derived : public Cloneable<Derived>
{};
 
N

Noah Roberts

On Tuesday, July 24, 2012 8:26:40 AM UTC-5, Peter Davis wrote:
&gt; If I make both Base and Cloneable be virtual base classes, this works,
&gt; but I don&amp;#39;t understand why this is necessary. Why doesn&amp;#39;t the template
&gt; just override the Base definition of clone()?

Because &quot;the template&quot; (Cloneable&lt;Derived&gt;) doesn't derive from Base. Try:

Additionally, you'll want to review what happens when you have the same function defined in two unrelated base classes but don't hide it:

http://crazycpp.wordpress.com/2011/03/28/name-resolution-and-overloading/
 
P

Peter Davis

Thank you. The actual code is more complex, as it is the implementation
side of a pimpl pattern, but I'll see if I can adapt this.
Additionally, you'll want to review what happens when you have the same function defined in two unrelated base classes but don't hide it:

http://crazycpp.wordpress.com/2011/03/28/name-resolution-and-overloading/

Thanks. I think a big part of the problem is that I was not able to make
the clone() method on Base be pure virtual. That's because there are
other classes, also abstract, whose default constructors created new
Base objects, so Base could not have any pure virtual methods.

Thank you both!
-pd
 

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

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top