#include <iostream>
struct Cloneable
{
protected:
Cloneable(){}
Cloneable(const Cloneable &){}
public:
virtual ~Cloneable(){}
Cloneable &operator=(const Cloneable &) = delete;
virtual Cloneable *Clone() const = 0;
template<typename TextendsCloneable>
static void ReleaseClone(TextendsCloneable *&clone)
{
Cloneable *c = dynamic_cast<Cloneable *>(clone);
// if(!c) throw CloningException();
clone = /*nullptr*/0;
c->ReleaseClone(), c = /*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;
};
template<typename InheritingClass>
struct Cloneable::Auto : public virtual Cloneable
{
virtual Cloneable *Clone() const
{
const InheritingClass *t = dynamic_cast<const InheritingClass *>(this);
if(!t)
{
// throw CloningException();
}
return new InheritingClass(*t);
}
protected:
virtual void ReleaseClone()
{
if(!dynamic_cast<const InheritingClass *>(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 = dynamic_cast<MyAbstractClass *>(a.Clone());
b->Tick();
Cloneable::ReleaseClone(b);
}