language: C++11 (gcc-4.7.2)
date: 181 days 13 hours ago
link:
visibility: public
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#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 InheritingClass *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(){}
    MyAbstractClass(const MyAbstractClass &){}
    virtual ~MyAbstractClass(){}
    
    MyAbstractClass &operator=(const MyAbstractClass &) = delete;
 
    virtual void Tick() = 0;
};
 
struct MyImplementationClass : public virtual MyAbstractClass, public virtual Cloneable::Auto<MyImplementationClass>
{
    MyImplementationClass(){}
    MyImplementationClass(const MyImplementationClass &){}
    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);
}
 
prog.cpp: In instantiation of 'Cloneable::Auto<MyImplementationClass>':
prog.cpp:75:1:   instantiated from here
prog.cpp:41:34: error: invalid covariant return type for 'InheritingClass* Cloneable::Auto<InheritingClass>::Clone() const [with InheritingClass = MyImplementationClass]'
prog.cpp:13:28: error:   overriding 'virtual Cloneable* Cloneable::Clone() const'