#include <iostream>
struct Cloneable
{
protected:
Cloneable(){}
Cloneable(const Cloneable &){}
public:
virtual ~Cloneable(){}
Cloneable &operator=(const Cloneable &) = delete;
virtual Cloneable *Clone() const = 0;
static void ReleaseClone(Cloneable *&clone)
{
clone->ReleaseClone(), clone = /*nullptr*/0;
}
protected:
virtual void ReleaseClone() = 0;
public:
// struct CloningException : public virtual Exception
// {
// CloningException(){}
// CloningException(const char *msg) : Exception(msg) {}
// CloningException(const CloningException &) = delete;
// CloningException &operator=(const CloningException &) = delete;
// virtual ~CloningException(){}
// };
template<typename InheritingClass>
struct Auto : public virtual Cloneable
{
typedef InheritingClass ICT;
virtual ICT *Clone() const
{
const ICT *t = dynamic_cast<const ICT *>(this);
if(!t)
{
// throw CloningException();
}
return new ICT(*t);
}
protected:
virtual void ReleaseClone()
{
if(!dynamic_cast<const ICT *>(this))
{
// throw CloningException();
}
delete this;
}
public:
virtual ~Auto(){}
};
};
struct MyAbstractClass : public virtual Cloneable
{
MyAbstractClass(){}
protected:
MyAbstractClass(const MyAbstractClass &){}
public:
virtual ~MyAbstractClass(){}
MyAbstractClass &operator=(const MyAbstractClass &) = delete;
virtual void Tick() = 0;
};
struct MyImplementationClass : public virtual MyAbstractClass, public virtual Cloneable::Auto<MyImplementationClass>
{
MyImplementationClass(){}
protected:
MyImplementationClass(const MyImplementationClass &){}
public:
virtual ~MyImplementationClass(){}
MyImplementationClass &operator=(const MyImplementationClass &) = delete;
virtual void Tick();
using Cloneable::Auto<MyImplementationClass>::Clone;
protected:
using Cloneable::Auto<MyImplementationClass>::ReleaseClone;
};
void MyImplementationClass::Tick()
{
std::cout << "Tick" << std::endl;
}
int main()
{
MyImplementationClass a;
MyAbstractClass *b = a.Clone();
b->Tick();
Cloneable::ReleaseClone(b);
}