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 | #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); } |
I2luY2x1ZGUgPGlvc3RyZWFtPgoKICAgIHN0cnVjdCBDbG9uZWFibGUKCXsKCXByb3RlY3RlZDoKCQlDbG9uZWFibGUoKXt9CgkJQ2xvbmVhYmxlKGNvbnN0IENsb25lYWJsZSAmKXt9CglwdWJsaWM6CgkJdmlydHVhbCB+Q2xvbmVhYmxlKCl7fQoKCQlDbG9uZWFibGUgJm9wZXJhdG9yPShjb25zdCBDbG9uZWFibGUgJikgPSBkZWxldGU7CgoJCXZpcnR1YWwgQ2xvbmVhYmxlICpDbG9uZSgpIGNvbnN0ID0gMDsKCQlzdGF0aWMgdm9pZCBSZWxlYXNlQ2xvbmUoQ2xvbmVhYmxlIComY2xvbmUpCgkJewoJCQljbG9uZS0+UmVsZWFzZUNsb25lKCksIGNsb25lID0gLypudWxscHRyKi8wOwoJCX0KCXByb3RlY3RlZDoKCQl2aXJ0dWFsIHZvaWQgUmVsZWFzZUNsb25lKCkgPSAwOwoJcHVibGljOgovLwkJc3RydWN0IENsb25pbmdFeGNlcHRpb24gOiBwdWJsaWMgdmlydHVhbCBFeGNlcHRpb24KLy8JCXsKLy8JCQlDbG9uaW5nRXhjZXB0aW9uKCl7fQovLwkJCUNsb25pbmdFeGNlcHRpb24oY29uc3QgY2hhciAqbXNnKSA6IEV4Y2VwdGlvbihtc2cpIHt9Ci8vCQkJQ2xvbmluZ0V4Y2VwdGlvbihjb25zdCBDbG9uaW5nRXhjZXB0aW9uICYpID0gZGVsZXRlOwovLwkJCUNsb25pbmdFeGNlcHRpb24gJm9wZXJhdG9yPShjb25zdCBDbG9uaW5nRXhjZXB0aW9uICYpID0gZGVsZXRlOwovLwkJCXZpcnR1YWwgfkNsb25pbmdFeGNlcHRpb24oKXt9Ci8vCQl9OwoKCQl0ZW1wbGF0ZTx0eXBlbmFtZSBJbmhlcml0aW5nQ2xhc3M+CgkJc3RydWN0IEF1dG8gOiBwdWJsaWMgdmlydHVhbCBDbG9uZWFibGUKCQl7CgkJCXR5cGVkZWYgSW5oZXJpdGluZ0NsYXNzIElDVDsKCQkJdmlydHVhbCBJQ1QgKkNsb25lKCkgY29uc3QKCQkJewoJCQkJY29uc3QgSUNUICp0ID0gZHluYW1pY19jYXN0PGNvbnN0IElDVCAqPih0aGlzKTsKCQkJCWlmKCF0KQoJCQkJewovLwkJCQkJdGhyb3cgQ2xvbmluZ0V4Y2VwdGlvbigpOwoJCQkJfQoJCQkJcmV0dXJuIG5ldyBJQ1QoKnQpOwoJCQl9CgkJcHJvdGVjdGVkOgoJCQl2aXJ0dWFsIHZvaWQgUmVsZWFzZUNsb25lKCkKCQkJewoJCQkJaWYoIWR5bmFtaWNfY2FzdDxjb25zdCBJQ1QgKj4odGhpcykpCgkJCQl7Ci8vCQkJCQl0aHJvdyBDbG9uaW5nRXhjZXB0aW9uKCk7CgkJCQl9CgkJCQlkZWxldGUgdGhpczsKCQkJfQoJCXB1YmxpYzoKCQkJdmlydHVhbCB+QXV0bygpe30KCQl9OwoJfTsKCnN0cnVjdCBNeUFic3RyYWN0Q2xhc3MgOiBwdWJsaWMgdmlydHVhbCBDbG9uZWFibGUKewogICAgTXlBYnN0cmFjdENsYXNzKCl7fQpwcm90ZWN0ZWQ6CiAgICBNeUFic3RyYWN0Q2xhc3MoY29uc3QgTXlBYnN0cmFjdENsYXNzICYpe30KcHVibGljOgogICAgdmlydHVhbCB+TXlBYnN0cmFjdENsYXNzKCl7fQogICAgCiAgICBNeUFic3RyYWN0Q2xhc3MgJm9wZXJhdG9yPShjb25zdCBNeUFic3RyYWN0Q2xhc3MgJikgPSBkZWxldGU7CgogICAgdmlydHVhbCB2b2lkIFRpY2soKSA9IDA7Cn07CgpzdHJ1Y3QgTXlJbXBsZW1lbnRhdGlvbkNsYXNzIDogcHVibGljIHZpcnR1YWwgTXlBYnN0cmFjdENsYXNzLCBwdWJsaWMgdmlydHVhbCBDbG9uZWFibGU6OkF1dG88TXlJbXBsZW1lbnRhdGlvbkNsYXNzPgp7CiAgICBNeUltcGxlbWVudGF0aW9uQ2xhc3MoKXt9CnByb3RlY3RlZDoKICAgIE15SW1wbGVtZW50YXRpb25DbGFzcyhjb25zdCBNeUltcGxlbWVudGF0aW9uQ2xhc3MgJil7fQpwdWJsaWM6CiAgICB2aXJ0dWFsIH5NeUltcGxlbWVudGF0aW9uQ2xhc3MoKXt9CiAgICAKICAgIE15SW1wbGVtZW50YXRpb25DbGFzcyAmb3BlcmF0b3I9KGNvbnN0IE15SW1wbGVtZW50YXRpb25DbGFzcyAmKSA9IGRlbGV0ZTsKICAgIAogICAgdmlydHVhbCB2b2lkIFRpY2soKTsKICAgIAogICAgdXNpbmcgQ2xvbmVhYmxlOjpBdXRvPE15SW1wbGVtZW50YXRpb25DbGFzcz46OkNsb25lOwpwcm90ZWN0ZWQ6CiAgICB1c2luZyBDbG9uZWFibGU6OkF1dG88TXlJbXBsZW1lbnRhdGlvbkNsYXNzPjo6UmVsZWFzZUNsb25lOwp9OwoKdm9pZCBNeUltcGxlbWVudGF0aW9uQ2xhc3M6OlRpY2soKQp7CiAgICBzdGQ6OmNvdXQgPDwgIlRpY2siIDw8IHN0ZDo6ZW5kbDsKfQoKaW50IG1haW4oKQp7CiAgICBNeUltcGxlbWVudGF0aW9uQ2xhc3MgYTsKICAgIE15QWJzdHJhY3RDbGFzcyAqYiA9IGEuQ2xvbmUoKTsKICAgIGItPlRpY2soKTsKICAgIENsb25lYWJsZTo6UmVsZWFzZUNsb25lKGIpOwp9Cg==
prog.cpp:32:3: error: invalid use of incomplete type 'struct Cloneable' prog.cpp:4:2: error: forward declaration of 'struct Cloneable' prog.cpp: In function 'int main()': prog.cpp:94:27: error: cannot declare variable 'a' to be of abstract type 'MyImplementationClass' prog.cpp:71:1: note: because the following virtual functions are pure within 'MyImplementationClass': prog.cpp:13:22: note: virtual Cloneable* Cloneable::Clone() const prog.cpp:19:16: note: virtual void Cloneable::ReleaseClone() prog.cpp:97:30: error: no matching function for call to 'Cloneable::ReleaseClone(MyAbstractClass*&)' prog.cpp:14:15: note: candidates are: static void Cloneable::ReleaseClone(Cloneable*&) prog.cpp:19:16: note: virtual void Cloneable::ReleaseClone() prog.cpp: In member function 'ICT* Cloneable::Auto<InheritingClass>::Clone() const [with InheritingClass = MyImplementationClass, ICT = MyImplementationClass]': prog.cpp:95:34: instantiated from here prog.cpp:41:22: error: cannot allocate an object of abstract type 'MyImplementationClass' prog.cpp:71:1: note: since type 'MyImplementationClass' has pure virtual functions
-
result: Compilation error (maybe you wish to see an example for C++11)


