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); } |
I2luY2x1ZGUgPGlvc3RyZWFtPgoKICAgIHN0cnVjdCBDbG9uZWFibGUKICAgIHsKICAgIHByb3RlY3RlZDoKICAgICAgICBDbG9uZWFibGUoKXt9CiAgICAgICAgQ2xvbmVhYmxlKGNvbnN0IENsb25lYWJsZSAmKXt9CiAgICBwdWJsaWM6CiAgICAgICAgdmlydHVhbCB+Q2xvbmVhYmxlKCl7fQoKICAgICAgICBDbG9uZWFibGUgJm9wZXJhdG9yPShjb25zdCBDbG9uZWFibGUgJikgPSBkZWxldGU7CgogICAgICAgIHZpcnR1YWwgQ2xvbmVhYmxlICpDbG9uZSgpIGNvbnN0ID0gMDsKICAgICAgICB0ZW1wbGF0ZTx0eXBlbmFtZSBUZXh0ZW5kc0Nsb25lYWJsZT4KICAgICAgICBzdGF0aWMgdm9pZCBSZWxlYXNlQ2xvbmUoVGV4dGVuZHNDbG9uZWFibGUgKiZjbG9uZSkKICAgICAgICB7CiAgICAgICAgICAgIENsb25lYWJsZSAqYyA9IGR5bmFtaWNfY2FzdDxDbG9uZWFibGUgKj4oY2xvbmUpOwovLyAgICAgICAgICBpZighYykgdGhyb3cgQ2xvbmluZ0V4Y2VwdGlvbigpOwogICAgICAgICAgICBjbG9uZSA9IC8qbnVsbHB0ciovMDsKICAgICAgICAgICAgYy0+UmVsZWFzZUNsb25lKCksIGMgPSAvKm51bGxwdHIqLzA7CiAgICAgICAgfQogICAgcHJvdGVjdGVkOgogICAgICAgIHZpcnR1YWwgdm9pZCBSZWxlYXNlQ2xvbmUoKSA9IDA7CiAgICBwdWJsaWM6Ci8vICAgICAgICBzdHJ1Y3QgQ2xvbmluZ0V4Y2VwdGlvbiA6IHB1YmxpYyB2aXJ0dWFsIEV4Y2VwdGlvbgovLyAgICAgICAgewovLyAgICAgICAgICAgIENsb25pbmdFeGNlcHRpb24oKXt9Ci8vICAgICAgICAgICAgQ2xvbmluZ0V4Y2VwdGlvbihjb25zdCBjaGFyICptc2cpIDogRXhjZXB0aW9uKG1zZykge30KLy8gICAgICAgICAgICBDbG9uaW5nRXhjZXB0aW9uKGNvbnN0IENsb25pbmdFeGNlcHRpb24gJikgPSBkZWxldGU7Ci8vICAgICAgICAgICAgQ2xvbmluZ0V4Y2VwdGlvbiAmb3BlcmF0b3I9KGNvbnN0IENsb25pbmdFeGNlcHRpb24gJikgPSBkZWxldGU7Ci8vICAgICAgICAgICAgdmlydHVhbCB+Q2xvbmluZ0V4Y2VwdGlvbigpe30KLy8gICAgICAgIH07CgogICAgICAgIHRlbXBsYXRlPHR5cGVuYW1lIEluaGVyaXRpbmdDbGFzcz4KICAgICAgICBzdHJ1Y3QgQXV0bzsKICAgIH07CiAgICAKICAgIHRlbXBsYXRlPHR5cGVuYW1lIEluaGVyaXRpbmdDbGFzcz4KICAgIHN0cnVjdCBDbG9uZWFibGU6OkF1dG8gOiBwdWJsaWMgdmlydHVhbCBDbG9uZWFibGUKICAgIHsKICAgICAgICB2aXJ0dWFsIEluaGVyaXRpbmdDbGFzcyAqQ2xvbmUoKSBjb25zdAogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgSW5oZXJpdGluZ0NsYXNzICp0ID0gZHluYW1pY19jYXN0PGNvbnN0IEluaGVyaXRpbmdDbGFzcyAqPih0aGlzKTsKICAgICAgICAgICAgaWYoIXQpCiAgICAgICAgICAgIHsKLy8gICAgICAgICAgICAgICAgICAgIHRocm93IENsb25pbmdFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICByZXR1cm4gbmV3IEluaGVyaXRpbmdDbGFzcygqdCk7CiAgICAgICAgfQogICAgcHJvdGVjdGVkOgogICAgICAgIHZpcnR1YWwgdm9pZCBSZWxlYXNlQ2xvbmUoKQogICAgICAgIHsKICAgICAgICAgICAgaWYoIWR5bmFtaWNfY2FzdDxjb25zdCBJbmhlcml0aW5nQ2xhc3MgKj4odGhpcykpCiAgICAgICAgICAgIHsKLy8gICAgICAgICAgICAgICAgICAgIHRocm93IENsb25pbmdFeGNlcHRpb24oKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkZWxldGUgdGhpczsKICAgICAgICB9CiAgICBwdWJsaWM6CiAgICAgICAgdmlydHVhbCB+QXV0bygpe30KICAgIH07CgpzdHJ1Y3QgTXlBYnN0cmFjdENsYXNzIDogcHVibGljIHZpcnR1YWwgQ2xvbmVhYmxlCnsKICAgIE15QWJzdHJhY3RDbGFzcygpe30KICAgIE15QWJzdHJhY3RDbGFzcyhjb25zdCBNeUFic3RyYWN0Q2xhc3MgJil7fQogICAgdmlydHVhbCB+TXlBYnN0cmFjdENsYXNzKCl7fQogICAgCiAgICBNeUFic3RyYWN0Q2xhc3MgJm9wZXJhdG9yPShjb25zdCBNeUFic3RyYWN0Q2xhc3MgJikgPSBkZWxldGU7CgogICAgdmlydHVhbCB2b2lkIFRpY2soKSA9IDA7Cn07CgpzdHJ1Y3QgTXlJbXBsZW1lbnRhdGlvbkNsYXNzIDogcHVibGljIHZpcnR1YWwgTXlBYnN0cmFjdENsYXNzLCBwdWJsaWMgdmlydHVhbCBDbG9uZWFibGU6OkF1dG88TXlJbXBsZW1lbnRhdGlvbkNsYXNzPgp7CiAgICBNeUltcGxlbWVudGF0aW9uQ2xhc3MoKXt9CiAgICBNeUltcGxlbWVudGF0aW9uQ2xhc3MoY29uc3QgTXlJbXBsZW1lbnRhdGlvbkNsYXNzICYpe30KICAgIHZpcnR1YWwgfk15SW1wbGVtZW50YXRpb25DbGFzcygpe30KICAgIAogICAgTXlJbXBsZW1lbnRhdGlvbkNsYXNzICZvcGVyYXRvcj0oY29uc3QgTXlJbXBsZW1lbnRhdGlvbkNsYXNzICYpID0gZGVsZXRlOwogICAgCiAgICB2aXJ0dWFsIHZvaWQgVGljaygpOwogICAgCi8vICAgIHVzaW5nIENsb25lYWJsZTo6QXV0bzxNeUltcGxlbWVudGF0aW9uQ2xhc3M+OjpDbG9uZTsKLy9wcm90ZWN0ZWQ6Ci8vICAgIHVzaW5nIENsb25lYWJsZTo6QXV0bzxNeUltcGxlbWVudGF0aW9uQ2xhc3M+OjpSZWxlYXNlQ2xvbmU7Cn07Cgp2b2lkIE15SW1wbGVtZW50YXRpb25DbGFzczo6VGljaygpCnsKICAgIHN0ZDo6Y291dCA8PCAiVGljayIgPDwgc3RkOjplbmRsOwp9CgppbnQgbWFpbigpCnsKICAgIE15SW1wbGVtZW50YXRpb25DbGFzcyBhOwogICAgTXlBYnN0cmFjdENsYXNzICpiID0gYS5DbG9uZSgpOwogICAgYi0+VGljaygpOwogICAgQ2xvbmVhYmxlOjpSZWxlYXNlQ2xvbmUoYik7Cn0K
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'
-
result: Compilation error (maybe you wish to see an example for C++11)


