How to make the templated classes keep the inheritance? - c++

The following is the simplified code to show my idea.
#include <iostream>
struct base {
virtual int test(){return 0;}
};
struct derived : public base {
virtual int test(){return 1;}
};
template <typename T>
struct foo : public T {
virtual int bar() { return 2;}
};
typedef foo<base> foo_base;
typedef foo<derived> foo_derived;
int main(int argc, char ** argv) {
base * p = new derived(); //It is OK.
std::cout<<p->test()<<std::endl;
foo_base * foo_p = new foo_derived(); //It is not OK
std::cout<<foo_p->bar()<<std::endl;
foo_base * foo_p2 =(foo_base *)(new foo_derived()); //It is working
std::cout<<foo_p2->bar()<<std::endl;
delete foo_p2;
delete foo_p;
delete p;
return 0;
}
I know it is not OK due to the template changing the class inheritance. Is there an elegant way to make the inheritance keep the same after applying the template ?
More specifically, is it possible to build an inheritance between foo<base> and foo<derived>, for example, by using some proxy templates or special pattern like CRTP to rebuild same inheritance after the template instantiation?

As said by Sam Varshavchik in the comments, you cannot automate this process completely since C++ does not have reflection, and thus can't list base classes. However, you've already gone down the route of typedefing your template instantiations, and this is the perfect place to list base classes yourself (hanges highlighted in comments):
struct base {
// Don't forget the virtual destructor for polymorphic destruction
virtual ~base() = default;
virtual int test() const { return 0; }
};
struct derived : base {
int test() const override { return 1; }
};
// U... is the list of thebase classes for T
template <typename T, typename... U>
struct foo : T, foo<U>... {
// ^^^^^^^^^^^ Inheritance is mirrored here
virtual int bar() const { return 2; }
};
// base has no base class
typedef foo<base> foo_base;
// derived has one base class, base.
typedef foo<derived, base> foo_derived;
Live example on Coliru

Related

How to override a templated function from non-templated parent class [duplicate]

Is it possible to declare some type of base class with template methods which i can override in derived classes? Following example:
#include <iostream>
#include <stdexcept>
#include <string>
class Base
{
public:
template<typename T>
std::string method() { return "Base"; }
};
class Derived : public Base
{
public:
template<typename T>
std::string method() override { return "Derived"; }
};
int main()
{
Base *b = new Derived();
std::cout << b->method<bool>() << std::endl;
return 0;
}
I would expect Derived as the output but it is Base. I assume it is necessary to make a templated wrapper class which receives the implementing class as the template parameter. But i want to make sure.
1) Your functions, in order to be polymorphic, should be marked with virtual
2) Templated functions are instantiated at the POI and can't be virtual (what is the signature??How many vtable entries do you reserve?). Templated functions are a compile-time mechanism, virtual functions a runtime one.
Some possible solutions involve:
Change design (recommended)
Follow another approach e.g. multimethod by Andrei Alexandrescu (http://www.icodeguru.com/CPP/ModernCppDesign/0201704315_ch11.html)
Template methods cannot be virtual. One solution is to use static polymorphism to simulate the behavior of "template virtual" methods:
#include <iostream>
#include <stdexcept>
#include <string>
template<typename D>
class Base
{
template<typename T>
std::string _method() { return "Base"; }
public:
template<typename T>
std::string method()
{
return static_cast<D&>(*this).template _method<T>();
}
};
class Derived : public Base<Derived>
{
friend class Base<Derived>;
template<typename T>
std::string _method() { return "Derived"; }
public:
//...
};
int main()
{
Base<Derived> *b = new Derived();
std::cout << b->method<bool>() << std::endl;
return 0;
}
where method is the interface and _method is the implementation. To simulate a pure virtual method, _method would absent from Base.
Unfortunately, this way Base changes to Base<Derived> so you can no longer e.g. have a container of Base*.
Also note that for a const method, static_cast<D&> changes to static_cast<const D&>. Similarly, for an rvalue-reference (&&) method, it changes to static_cast<D&&>.
Another possible aproach to make your example work as you expect is to use std::function:
class Base {
public:
Base() {
virtualFunction = [] () -> string { return {"Base"}; };
}
template <class T> string do_smth() { return virtualFunction(); }
function<string()> virtualFunction;
};
class Derived : public Base {
public:
Derived() {
virtualFunction = [] () -> string { return {"Derived"}; };
}
};
int main() {
auto ptr = unique_ptr<Base>(new Derived);
cout << ptr->do_smth<bool>() << endl;
}
This outputs "Derived". I'm not sure that this is what you realy want, but I hope it will help you..
I had the same problem, but I actually came up with a working solution. The best way to show the solution is by an example:
What we want(doesn't work, since you can't have virtual templates):
class Base
{
template <class T>
virtual T func(T a, T b) {};
}
class Derived
{
template <class T>
T func(T a, T b) { return a + b; };
}
int main()
{
Base* obj = new Derived();
std::cout << obj->func(1, 2) << obj->func(std::string("Hello"), std::string("World")) << obj->func(0.2, 0.1);
return 0;
}
The solution(prints 3HelloWorld0.3):
class BaseType
{
public:
virtual BaseType* add(BaseType* b) { return {}; };
};
template <class T>
class Type : public BaseType
{
public:
Type(T t) : value(t) {};
BaseType* add(BaseType* b)
{
Type<T>* a = new Type<T>(value + ((Type<T>*)b)->value);
return a;
};
T getValue() { return value; };
private:
T value;
};
class Base
{
public:
virtual BaseType* function(BaseType* a, BaseType* b) { return {}; };
template <class T>
T func(T a, T b)
{
BaseType* argA = new Type<T>(a);
BaseType* argB = new Type<T>(b);
BaseType* value = this->function(argA, argB);
T result = ((Type<T>*)value)->getValue();
delete argA;
delete argB;
delete value;
return result;
};
};
class Derived : public Base
{
public:
BaseType* function(BaseType* a, BaseType* b)
{
return a->add(b);
};
};
int main()
{
Base* obj = new Derived();
std::cout << obj->func(1, 2) << obj->func(std::string("Hello"), std::string("World")) << obj->func(0.2, 0.1);
return 0;
}
We use the BaseType class to represent any datatype or class you would usually use in a template. The members(and possibly operators) you would use in a template are described here with the virtual tag. Note that the pointers are necessary in order to get the polymorphism to work.
Type is a template class that extends Derived. This actually represents a specific type, for example Type<int>. This class is very important, since it allows us to convert any type into the BaseType. The definition of the members we described described in BaseType are implemented here.
function is the function we want to override. Instead of using a real template we use pointers to BaseType to represent a typename. The actual template function is in the Base class defined as func. It basically just calls function and converts T to Type<T>. If we now extend from Base and override function, the new overridden function gets called for the derived class.

C++ Separated static field for each derived class

For quite a long time as was thinking about solution to my problem and I finally came to point when I have no other ideas but to ask here.
I have following problem.
Short version. How to inherit static field from base class, but make it unique in each derived class and keep possibility to upcast those classes to parent class?
Long version. I need to create some kind of basic interface for set of classes. Each of this classes need to have one static field and one static method. But I want to be able to pass all those classes as parameters to one universal function which uses those static members. So I was thinking about inheriting them all from one base class.
But of course I can't simply inherit static members and expect them to be unique in each child class. I was trying to use Curiously Recurring Template Pattern (CRTP), but it forces me to make this universal function template too and directly give it class name during each call. That's not good for me.
Also I have problems with making CRTP works when more than one level of inheritance is used (i.e. when I want to derive one more class from class derived from this template base class). Is there any way to achieve what I need?
I know that similar questions were already asked but in most of them authors were glad with CRTP. For me it doesn't seem like solution good enough.
//pseudo-code for what I need, doesn't work of course
class Base {
public:
static int x;
static int GetX() {return x;}
}
class Derived : public Base {};
class NextDerived : public Derived {};
class NextDerived2 : public Derived {};
void Foo(Base& a) {a.x = 10;}
int main {
NextDerived d;
NextDerived2 d2;
Foo(d);
Foo(d2); //both Foos modify different static variables
}
//CRTP attempt
template <class C>
class Base {
public:
static int x;
static int GetX() {return x}
};
class Derived : public Base<Derived> {};
int Derived::x = 0;
template <class C>
void Foo(Base<C>& b) {
b.x = 10;
return;
};
int main() {
Derived d;
Foo<Derived>(d);
}
Keep in mind that static variables must also be defined. So for every derived type that you need a separate static variable for, you'll need to define it as well.
Instead, you could use a std::map and a type-id hash to do something similar without the need to clutter your base class. Additionally, this allows you to have any type be used, example:
#include <iostream>
#include <map>
#define out(v) std::cout << v << std::endl
static std::map<std::size_t, int> ExsAndOhs;
template < typename T >
static std::size_t type_id() // in case you don't want RTTI on
{
static char tid;
return reinterpret_cast<std::size_t>(&tid);
}
template < typename T >
void Foo(int _x) { ExsAndOhs[type_id<T>()] = _x; }
template < typename T >
void Foo(T& obj, int _x) { ExsAndOhs[type_id<T>()] = _x; }
template < typename T >
void Print() { out(ExsAndOhs[type_id<T>()]); }
template < typename T >
void Print(T& obj) { out(ExsAndOhs[type_id<T>()]); }
class Base {};
class Derived : public Base {};
class D2 : public Base {};
int main(int argc, char* argv[])
{
// using explicit templates
Foo<Base>(100);
Foo<Derived>(10);
Foo<D2>(42);
Foo<long>(65535);
Foo<int>(1955);
Print<Base>();
Print<Derived>();
Print<D2>();
Print<long>();
Print<int>();
Base b;
Derived d;
D2 d2;
int x = 1;
long y = 1;
// using template deduction
Foo(b, 10);
Foo(d, 42);
Foo(d2, 100);
Print(b);
Print(d);
Print(d2);
Print(x); // still prints 1955
Print(y); // still prints 65535
return 0;
}
This also avoids the need to declare each derived classes static members.
This may not be a good solution for your specific use case, but it is an alternative that achieves what you're asking.
Hope that can help.
Does this CRTP style work for you?
#include <iostream>
using namespace std;
template<class T>
class Base {
public:
static int x;
static int GetX() {return x;}
};
template<class T>
class Derived : public Base <Derived<T> >{};
class NextDerived : public Derived<NextDerived> {};
class NextDerived2 : public Derived<NextDerived2> {};
static int count = 0;
template<class T> int Base<T>::x = 0;
template<class T>
void Foo(Base<Derived<T> >& a) {
a.x = count++;
};
int main() {
NextDerived d;
NextDerived2 d2;
Foo(d);
Foo(d2);
cout << d.GetX() << " " << d2.GetX() << endl;
return 0;
}

Override template member in Interface

Is it possible to declare some type of base class with template methods which i can override in derived classes? Following example:
#include <iostream>
#include <stdexcept>
#include <string>
class Base
{
public:
template<typename T>
std::string method() { return "Base"; }
};
class Derived : public Base
{
public:
template<typename T>
std::string method() override { return "Derived"; }
};
int main()
{
Base *b = new Derived();
std::cout << b->method<bool>() << std::endl;
return 0;
}
I would expect Derived as the output but it is Base. I assume it is necessary to make a templated wrapper class which receives the implementing class as the template parameter. But i want to make sure.
1) Your functions, in order to be polymorphic, should be marked with virtual
2) Templated functions are instantiated at the POI and can't be virtual (what is the signature??How many vtable entries do you reserve?). Templated functions are a compile-time mechanism, virtual functions a runtime one.
Some possible solutions involve:
Change design (recommended)
Follow another approach e.g. multimethod by Andrei Alexandrescu (http://www.icodeguru.com/CPP/ModernCppDesign/0201704315_ch11.html)
Template methods cannot be virtual. One solution is to use static polymorphism to simulate the behavior of "template virtual" methods:
#include <iostream>
#include <stdexcept>
#include <string>
template<typename D>
class Base
{
template<typename T>
std::string _method() { return "Base"; }
public:
template<typename T>
std::string method()
{
return static_cast<D&>(*this).template _method<T>();
}
};
class Derived : public Base<Derived>
{
friend class Base<Derived>;
template<typename T>
std::string _method() { return "Derived"; }
public:
//...
};
int main()
{
Base<Derived> *b = new Derived();
std::cout << b->method<bool>() << std::endl;
return 0;
}
where method is the interface and _method is the implementation. To simulate a pure virtual method, _method would absent from Base.
Unfortunately, this way Base changes to Base<Derived> so you can no longer e.g. have a container of Base*.
Also note that for a const method, static_cast<D&> changes to static_cast<const D&>. Similarly, for an rvalue-reference (&&) method, it changes to static_cast<D&&>.
Another possible aproach to make your example work as you expect is to use std::function:
class Base {
public:
Base() {
virtualFunction = [] () -> string { return {"Base"}; };
}
template <class T> string do_smth() { return virtualFunction(); }
function<string()> virtualFunction;
};
class Derived : public Base {
public:
Derived() {
virtualFunction = [] () -> string { return {"Derived"}; };
}
};
int main() {
auto ptr = unique_ptr<Base>(new Derived);
cout << ptr->do_smth<bool>() << endl;
}
This outputs "Derived". I'm not sure that this is what you realy want, but I hope it will help you..
I had the same problem, but I actually came up with a working solution. The best way to show the solution is by an example:
What we want(doesn't work, since you can't have virtual templates):
class Base
{
template <class T>
virtual T func(T a, T b) {};
}
class Derived
{
template <class T>
T func(T a, T b) { return a + b; };
}
int main()
{
Base* obj = new Derived();
std::cout << obj->func(1, 2) << obj->func(std::string("Hello"), std::string("World")) << obj->func(0.2, 0.1);
return 0;
}
The solution(prints 3HelloWorld0.3):
class BaseType
{
public:
virtual BaseType* add(BaseType* b) { return {}; };
};
template <class T>
class Type : public BaseType
{
public:
Type(T t) : value(t) {};
BaseType* add(BaseType* b)
{
Type<T>* a = new Type<T>(value + ((Type<T>*)b)->value);
return a;
};
T getValue() { return value; };
private:
T value;
};
class Base
{
public:
virtual BaseType* function(BaseType* a, BaseType* b) { return {}; };
template <class T>
T func(T a, T b)
{
BaseType* argA = new Type<T>(a);
BaseType* argB = new Type<T>(b);
BaseType* value = this->function(argA, argB);
T result = ((Type<T>*)value)->getValue();
delete argA;
delete argB;
delete value;
return result;
};
};
class Derived : public Base
{
public:
BaseType* function(BaseType* a, BaseType* b)
{
return a->add(b);
};
};
int main()
{
Base* obj = new Derived();
std::cout << obj->func(1, 2) << obj->func(std::string("Hello"), std::string("World")) << obj->func(0.2, 0.1);
return 0;
}
We use the BaseType class to represent any datatype or class you would usually use in a template. The members(and possibly operators) you would use in a template are described here with the virtual tag. Note that the pointers are necessary in order to get the polymorphism to work.
Type is a template class that extends Derived. This actually represents a specific type, for example Type<int>. This class is very important, since it allows us to convert any type into the BaseType. The definition of the members we described described in BaseType are implemented here.
function is the function we want to override. Instead of using a real template we use pointers to BaseType to represent a typename. The actual template function is in the Base class defined as func. It basically just calls function and converts T to Type<T>. If we now extend from Base and override function, the new overridden function gets called for the derived class.

C++ Templates. Can't use inherited function

Well this has been giving me grief...
#include <iostream>
class InterfaceClass
{
public:
void test()
{
std::cout<<"Hello there.\n";
}
};
template <class T>
class TemplateClass
{
public:
T t;
};
class TestClass: public InterfaceClass
{};
class TestInheritor
{
public:
TemplateClass < InterfaceClass >* templateInherit;
InterfaceClass* normalInherit;
void test()
{
normalInherit->test();
templateInherit->t.test();
}
};
int main (int nargs, char ** arg)
{
TestInheritor ti;
ti.normalInherit = new TestClass; // THIS ONE COMPILES OKAY.
//ti.templateInherit = new TemplateClass <TestClass>; // COMPILE ERROR.
// THIS WORKS THOUGH
TemplateClass <TestClass> * tempClass = new TemplateClass <TestClass>;
ti.templateInherit=(TemplateClass <InterfaceClass>*)tempClass; // WHY DO I HAVE TO EXPLICITLY CAST?
// OUTPUT WORKS AS EXPECTED.
ti.test();
return 0;
}
The normal inheritance example works just fine. The TestClass is automatically converted to a InterfaceClass. However, with the template example, it gives a compile error:
error: cannot convert 'TemplateClass<TestClass>*' to 'TemplateClass<InterfaceClass>*' in assignment
In my mind, it is obvious that you can convert TemplateClass<TestClass>* to TemplateClass<InterfaceClass>*... So what am I missing here?
I can fix it by explicitly casting the template class to the base class, I am able to use the inherited test() function without any problem... So why am I required to explicitly cast the template class?
Sorry if that's confusing... It's hard for me to explain this problem.
Okay, I understand the issue a little more. I have decided to add a template to TestInheritor like so:
template <class T2>
class TestInheritor
{
public:
TemplateClass < T2 >* templateInherit;
InterfaceClass* normalInherit;
void test()
{
normalInherit->test();
templateInherit->t.test();
}
};
int main (int nargs, char ** arg)
{
TestInheritor <TestClass> ti;
ti.normalInherit = new TestClass;
ti.templateInherit = new TemplateClass <TestClass>;
ti.test();
return 0;
}
Probably not the perfect solution, but it works for my purposes.
Ah, and I see your solution:
#include <iostream>
class InterfaceClass
{
public:
void test()
{
std::cout<<"Hello there.\n";
}
};
class TestClass: public InterfaceClass
{};
template <class T>
class TemplateClass
{
public:
T t;
};
template<>
class TemplateClass<TestClass> : public TemplateClass<InterfaceClass>
{
public:
};
class TestInheritor
{
public:
TemplateClass < InterfaceClass >* templateInherit;
InterfaceClass* normalInherit;
void test()
{
normalInherit->test();
templateInherit->t.test();
}
};
int main (int nargs, char ** arg)
{
TestInheritor ti;
ti.normalInherit = new TestClass;
ti.templateInherit = new TemplateClass <TestClass>;
ti.test();
return 0;
}
Consider
class Base
{};
class Derived : public Base
{};
template<typename T>
class TemplateClass
{};
Contrary to what you might think, TemplateClass<Derived> is not a TemplateClass<Base> in the sence of inheritance, so pointers to the former can't be implicitly converted to pointers of the later.
So why does explicitly casting a pointer to TemplateClass<Derived> to a pointer of TemplateClass<Base> compile? Because any pointer of a certain type may be explicitly cast to any pointer of any other type, however there are no guarantees the conversion is valid! You could for instance just as well write
int* i = (int*) new TemplateClass<Derived>;
and it would compile just fine, even though it is clearly an invalid conversion.
Now why does your example work? Sheer luck. At the point a pointer containing an address obtained through an invalid pointer cast gets dereferenced, the program becomes invalid and its bahavior undefined. Anything can happen, including doing what you would expect.
If you want TemplateClass<Derived> to be a TemplateClass<Base> in the sence of inheritance, you can define an specialization of TemplateClass<> stating this relationship explicitly, like the following:
template<>
class TemplateClass<Derived> : public TemplateClass<Base>
{};

Cloning Pointers C++

This question is regarding copying and pointer polymorphism. Consider the code below. We have two classes: Base and Derived, which are just regular objects. Then we've got class Foo, which has a pointer to Base as its only member.
The typical usage of Foo is described in the main function. The input to Foo::SetMemberX may or may not be a temporary object.
The problem is that I want Foo::SetMember to create a proper copy of the passed object, and assign its address as a Base* to Foo::mMember.
I've managed to come up with 4 possible solution, none of which seem very elegant to me. The first three are shown in the code below in Foo::SetMember1, Foo::SetMember2, and Foo::SetMember3. The 4th option is to leave the memory allocation to the user (ex. foo.SetMember(new Derived())), which is not very desirable for obvious memory safety issues. Foo should be responsible for memory management, not the user.
#include <iostream>
template <typename tBase, typename tPointer>
void ClonePointer(tBase*& destination, const tPointer* pointer)
{
destination = static_cast<tBase*>(new tPointer(*pointer));
}
// Base can be a virtual class
class Base
{
public:
virtual void Function()
{
std::cout << "Base::Function()" << std::endl;
}
virtual Base* Clone() const = 0;
};
class Derived : public Base
{
public:
virtual void Function()
{
std::cout << "Derived::Function()" << std::endl;
}
virtual Base* Clone() const
{
return new Derived(*this);
}
};
class Foo
{
public:
Foo() : mMember(NULL) { }
~Foo()
{
if (mMember != NULL)
{
delete mMember;
mMember = NULL;
}
}
template <typename T>
void SetMember1(const T& t)
{
if (mMember != NULL)
{
delete mMember;
mMember = NULL;
}
ClonePointer(mMember, &t);
}
void SetMember2(const Base& b)
{
mMember = b.Clone();
}
template <typename T>
void SetMember3(const T& t)
{
if (mMember != NULL)
{
delete mMember;
mMember = NULL;
}
mMember = new T(t);
}
Base& GetMember()
{
return *mMember;
}
private:
Base* mMember;
};
int main(int argc, char** argv)
{
{
Foo f1;
Foo f2;
Foo f3;
// The input may or may not be a tempoary/RValue reference
f1.SetMember1(Derived());
f2.SetMember2(Derived());
f3.SetMember3(Derived());
f1.GetMember().Function();
f2.GetMember().Function();
f3.GetMember().Function();
}
// Output:
// Derived::Function();
// Derived::Function();
// Derived::Function();
system("pause"); // for quick testing
}
The problem with the first method (Foo::SetMember1) is that I have a random, free, template function, and a template accessore (see the problem with the third method below).
The problem with the second method (Foo::SetMember2) is that every derived class must implement its own Clone function. This is too much boilerplate code for the class user, as there will be a lot of classes deriving from Base. If I could somehow automate this, or create a base Cloneable class (without each Base-derived class having to explicitly calling it) with an implemented template Clone function, this would be the ideal solution.
The problem with the third method (Foo::SetMember3) is that I'd need a template accessor for Foo. This may not always be possible, especially because of how virtual template methods are not allowed in non-template classes (Foo cannot be a template itself), which is a functionality that might be required.
My questions are:
Are these the only options I have?
Is there a better, more elegant solution to this problem that I'm missing?
Is there any way to create a base Cloneable class and derive Base from it, and have cloning automagically happen for DerivedType::Clone()?
Here's a more or less robust Clonable class that can be inherited to any depth. It uses CRTP and Alecsandrescu-style interleaving inheritance pattern.
#include <iostream>
// set up a little named template parameters rig
template <class X> struct Parent{};
template <class X> struct Self{};
template<class A, class B> struct ParentChild;
// can use ...< Parent<X>, Self<Y> >...
template<class A, class B> struct ParentChild< Parent<A>, Self<B> >
{
typedef A parent_type;
typedef B child_type;
};
// or ...< Self<Y>, Parent<X> >
template<class A, class B> struct ParentChild< Self<B>, Parent<A> >
{
typedef A parent_type;
typedef B child_type;
};
// nothing, really
struct Nada
{
// except the virtual dtor! Everything clonable will inherit from here.
virtual ~Nada() {}
};
// The Clonable template. Accepts two parameters:
// the child class (as in CRTP), and the parent class (one to inherit from)
// In any order.
template <class A, class B = Parent<Nada> > class Clonable :
public ParentChild<A,B>::parent_type
{
public:
// a nice name to refer to in the child class, instead of Clonable<A,B>
typedef Clonable Parent;
// this is our child class
typedef typename ParentChild<A,B>::child_type child_type;
// This is the clone() function returning the cloned object
// Non-virtual, because the compiler has trouble with covariant return
// type here. We have to implemens something similar, by having non-virtual
// that returns the covariant type calling virtual that returns the
// base type, and some cast.
child_type* clone()
{
return static_cast<child_type*>(private_clone());
}
// forward some constructor, C++11 style
template<typename... Args> Clonable(Args&&... args):
ParentChild<A,B>::parent_type(args...) {}
private:
// this is the main virtual clone function
// allocates the new child_type object and copies itself
// with the copy constructor
virtual Nada* private_clone()
{
// we *know* we're the child_type object
child_type* me = static_cast<child_type*>(this);
return new child_type(*me);
};
};
// Test drive and usage example
class Foo : public Clonable < Self<Foo> >
{
public:
Foo (int) { std::cout << "Foo::Foo(int)\n"; }
Foo (double, char) { std::cout << "Foo::Foo(double, char)\n"; }
Foo (const Foo&) { std::cout << "Foo::Foo(Foo&)\n"; }
};
class Bar : public Clonable < Self<Bar>, Parent<Foo> >
{
public:
// cannot say Bar (int i) : Foo(i), unfortunately, because Foo is not
// our immediate parent
// have to use the Parent alias
Bar (int i) : Parent(i)
{ std::cout << "Bar::Bar(int)\n"; }
Bar (double a, char b) : Parent(a, b)
{ std::cout << "Bar::Bar(double, char)\n"; }
Bar (const Bar& b) : Parent(b)
{ std::cout << "Bar::Bar(Bar&)\n"; }
~Bar() { std::cout << "Bar::~Bar()\n"; }
};
int main ()
{
Foo* foo1 = new Bar (123);
Foo* foo2 = foo1->clone(); // this is really a Bar
delete foo1;
delete foo2;
}
For 2nd method, you can use CRTP and you won't need to write clone method in every derived class:
struct Base {
virtual ~Base() {}
virtual Base *clone() const = 0;
};
template <typename Derived>
struct CloneableBase : public Base {
virtual Base *clone() const {
return new Derived(static_cast<Derived const&>(*this));
}
};
struct Derived: CloneableBase<Derived> {};