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 102 103 104 105 | #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); } |
I2luY2x1ZGUgPGlvc3RyZWFtPgoKICAgIHN0cnVjdCBDbG9uZWFibGUKICAgIHsKICAgIHByb3RlY3RlZDoKICAgICAgICBDbG9uZWFibGUoKXt9CiAgICAgICAgQ2xvbmVhYmxlKGNvbnN0IENsb25lYWJsZSAmKXt9CiAgICBwdWJsaWM6CiAgICAgICAgdmlydHVhbCB+Q2xvbmVhYmxlKCl7fQoKICAgICAgICBDbG9uZWFibGUgJm9wZXJhdG9yPShjb25zdCBDbG9uZWFibGUgJikgPSBkZWxldGU7CgogICAgICAgIHZpcnR1YWwgQ2xvbmVhYmxlICpDbG9uZSgpIGNvbnN0ID0gMDsKICAgICAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUZXh0ZW5kc0Nsb25lYWJsZT4KICAgICAgICBzdGF0aWMgdm9pZCBSZWxlYXNlQ2xvbmUoVGV4dGVuZHNDbG9uZWFibGUgKiZjbG9uZSkKICAgICAgICB7CiAgICAgICAgICAgIENsb25lYWJsZSAqYyA9IGR5bmFtaWNfY2FzdDxDbG9uZWFibGUgKj4oY2xvbmUpOwovLyAgICAgICAgICBpZighYykgdGhyb3cgQ2xvbmluZ0V4Y2VwdGlvbigpOwogICAgICAgICAgICBjbG9uZSA9IC8qbnVsbHB0ciovMDsKICAgICAgICAgICAgYy0+UmVsZWFzZUNsb25lKCksIGMgPSAvKm51bGxwdHIqLzA7CiAgICAgICAgfQogICAgcHJvdGVjdGVkOgogICAgICAgIHZpcnR1YWwgdm9pZCBSZWxlYXNlQ2xvbmUoKSA9IDA7CiAgICBwdWJsaWM6Ci8vICAgICAgICBzdHJ1Y3QgQ2xvbmluZ0V4Y2VwdGlvbiA6IHB1YmxpYyB2aXJ0dWFsIEV4Y2VwdGlvbgovLyAgICAgICAgewovLyAgICAgICAgICAgIENsb25pbmdFeGNlcHRpb24oKXt9Ci8vICAgICAgICAgICAgQ2xvbmluZ0V4Y2VwdGlvbihjb25zdCBjaGFyICptc2cpIDogRXhjZXB0aW9uKG1zZykge30KLy8gICAgICAgICAgICBDbG9uaW5nRXhjZXB0aW9uKGNvbnN0IENsb25pbmdFeGNlcHRpb24gJikgPSBkZWxldGU7Ci8vICAgICAgICAgICAgQ2xvbmluZ0V4Y2VwdGlvbiAmb3BlcmF0b3I9KGNvbnN0IENsb25pbmdFeGNlcHRpb24gJikgPSBkZWxldGU7Ci8vICAgICAgICAgICAgdmlydHVhbCB+Q2xvbmluZ0V4Y2VwdGlvbigpe30KLy8gICAgICAgIH07CgogICAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIEluaGVyaXRpbmdDbGFzcz4KICAgICAgICBzdHJ1Y3QgQXV0bzsKICAgIH07CiAgICAKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEluaGVyaXRpbmdDbGFzcz4KICAgIHN0cnVjdCBDbG9uZWFibGU6OkF1dG8gOiBwdWJsaWMgdmlydHVhbCBDbG9uZWFibGUKICAgIHsKICAgICAgICB2aXJ0dWFsIENsb25lYWJsZSAqQ2xvbmUoKSBjb25zdAogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgSW5oZXJpdGluZ0NsYXNzICp0ID0gZHluYW1pY19jYXN0PGNvbnN0IEluaGVyaXRpbmdDbGFzcyAqPih0aGlzKTsKICAgICAgICAgICAgaWYoIXQpCiAgICAgICAgICAgIHsKLy8gICAgICAgICAgICAgICAgICAgIHRocm93IENsb25pbmdFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3IEluaGVyaXRpbmdDbGFzcygqdCk7CiAgICAgICAgfQogICAgcHJvdGVjdGVkOgogICAgICAgIHZpcnR1YWwgdm9pZCBSZWxlYXNlQ2xvbmUoKQogICAgICAgIHsKICAgICAgICAgICAgaWYoIWR5bmFtaWNfY2FzdDxjb25zdCBJbmhlcml0aW5nQ2xhc3MgKj4odGhpcykpCiAgICAgICAgICAgIHsKLy8gICAgICAgICAgICAgICAgICAgIHRocm93IENsb25pbmdFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWxldGUgdGhpczsKICAgICAgICB9CiAgICBwdWJsaWM6CiAgICAgICAgdmlydHVhbCB+QXV0bygpe30KICAgIH07CgpzdHJ1Y3QgTXlBYnN0cmFjdENsYXNzIDogcHVibGljIHZpcnR1YWwgQ2xvbmVhYmxlCnsKICAgIE15QWJzdHJhY3RDbGFzcygpe30KcHJvdGVjdGVkOgogICAgTXlBYnN0cmFjdENsYXNzKGNvbnN0IE15QWJzdHJhY3RDbGFzcyAmKXt9CnB1YmxpYzoKICAgIHZpcnR1YWwgfk15QWJzdHJhY3RDbGFzcygpe30KICAgIAogICAgTXlBYnN0cmFjdENsYXNzICZvcGVyYXRvcj0oY29uc3QgTXlBYnN0cmFjdENsYXNzICYpID0gZGVsZXRlOwoKICAgIHZpcnR1YWwgdm9pZCBUaWNrKCkgPSAwOwp9OwoKc3RydWN0IE15SW1wbGVtZW50YXRpb25DbGFzcyA6IHB1YmxpYyB2aXJ0dWFsIE15QWJzdHJhY3RDbGFzcywgcHVibGljIHZpcnR1YWwgQ2xvbmVhYmxlOjpBdXRvPE15SW1wbGVtZW50YXRpb25DbGFzcz4KewogICAgTXlJbXBsZW1lbnRhdGlvbkNsYXNzKCl7fQpwcm90ZWN0ZWQ6CiAgICBNeUltcGxlbWVudGF0aW9uQ2xhc3MoY29uc3QgTXlJbXBsZW1lbnRhdGlvbkNsYXNzICYpe30KcHVibGljOgogICAgdmlydHVhbCB+TXlJbXBsZW1lbnRhdGlvbkNsYXNzKCl7fQogICAgCiAgICBNeUltcGxlbWVudGF0aW9uQ2xhc3MgJm9wZXJhdG9yPShjb25zdCBNeUltcGxlbWVudGF0aW9uQ2xhc3MgJikgPSBkZWxldGU7CiAgICAKICAgIHZpcnR1YWwgdm9pZCBUaWNrKCk7CiAgICAKICAgIHVzaW5nIENsb25lYWJsZTo6QXV0bzxNeUltcGxlbWVudGF0aW9uQ2xhc3M+OjpDbG9uZTsKcHJvdGVjdGVkOgogICAgdXNpbmcgQ2xvbmVhYmxlOjpBdXRvPE15SW1wbGVtZW50YXRpb25DbGFzcz46OlJlbGVhc2VDbG9uZTsKfTsKCnZvaWQgTXlJbXBsZW1lbnRhdGlvbkNsYXNzOjpUaWNrKCkKewogICAgc3RkOjpjb3V0IDw8ICJUaWNrIiA8PCBzdGQ6OmVuZGw7Cn0KCmludCBtYWluKCkKewogICAgTXlJbXBsZW1lbnRhdGlvbkNsYXNzIGE7CiAgICBNeUFic3RyYWN0Q2xhc3MgKmIgPSBkeW5hbWljX2Nhc3Q8TXlBYnN0cmFjdENsYXNzICo+KGEuQ2xvbmUoKSk7CiAgICBiLT5UaWNrKCk7CiAgICBDbG9uZWFibGU6OlJlbGVhc2VDbG9uZShiKTsKfQo=
prog.cpp: In member function 'Cloneable* Cloneable::Auto<InheritingClass>::Clone() const [with InheritingClass = MyImplementationClass, Cloneable = Cloneable]': prog.cpp:101:66: instantiated from here prog.cpp:80:5: error: 'MyImplementationClass::MyImplementationClass(const MyImplementationClass&)' is protected prog.cpp:48:42: error: within this context
-
result: Compilation error (maybe you wish to see an example for C++11)


