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 | #include <memory> #include <cstdio> #include <string> namespace clone_ptr_detail { template <class T> class clone_ptr_helper_base { public: virtual ~clone_ptr_helper_base() {} virtual T* clone(const T* source) const = 0; virtual void destroy(const T* p) const = 0; }; template <class T, class U> class clone_ptr_helper: public clone_ptr_helper_base<T> { public: virtual T* clone(const T* source) const { return new U(static_cast<const U&>(*source)); } virtual void destroy(const T* p) const { delete static_cast<const U*>(p); } }; } template <class T> class clone_ptr { T* ptr; std::shared_ptr<clone_ptr_detail::clone_ptr_helper_base<T>> ptr_helper; public: template <class U> explicit clone_ptr(U* p): ptr(p), ptr_helper(new clone_ptr_detail::clone_ptr_helper<T, U>()) {} clone_ptr(const clone_ptr& other): ptr(other.ptr_helper->clone(other.ptr)), ptr_helper(other.ptr_helper) {} clone_ptr& operator=(clone_ptr rhv) { swap(rhv); return *this; } ~clone_ptr() { ptr_helper->destroy(ptr); } T* get() const { /*error checking here*/ return ptr; } T& operator* () const { return *get(); } T* operator-> () const { return get(); } void swap(clone_ptr& other) { std::swap(ptr, other.ptr); ptr_helper.swap(other.ptr_helper); } }; struct A { virtual void foo() { puts("A::foo"); } }; struct B: A { std::string id; B(const std::string& id): id(id) {} B(const B& other): id("Copy of " + other.id) {} ~B() { puts("~B"); } virtual void foo() { puts(id.c_str()); } }; int main() { clone_ptr<A> a(new B("B_instance")); clone_ptr<A> b(a); a->foo(); (*b).foo(); clone_ptr<A> c(new A); a = c; a->foo(); } |
I2luY2x1ZGUgPG1lbW9yeT4KI2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPHN0cmluZz4KCm5hbWVzcGFjZSBjbG9uZV9wdHJfZGV0YWlsCnsKdGVtcGxhdGUgPGNsYXNzIFQ+CmNsYXNzIGNsb25lX3B0cl9oZWxwZXJfYmFzZQp7CnB1YmxpYzoKICAgIHZpcnR1YWwgfmNsb25lX3B0cl9oZWxwZXJfYmFzZSgpIHt9CiAgICB2aXJ0dWFsIFQqIGNsb25lKGNvbnN0IFQqIHNvdXJjZSkgY29uc3QgPSAwOwogICAgdmlydHVhbCB2b2lkIGRlc3Ryb3koY29uc3QgVCogcCkgY29uc3QgPSAwOwp9OwoKdGVtcGxhdGUgPGNsYXNzIFQsIGNsYXNzIFU+CmNsYXNzIGNsb25lX3B0cl9oZWxwZXI6IHB1YmxpYyBjbG9uZV9wdHJfaGVscGVyX2Jhc2U8VD4KewpwdWJsaWM6CiAgICB2aXJ0dWFsIFQqIGNsb25lKGNvbnN0IFQqIHNvdXJjZSkgY29uc3QKICAgIHsKICAgICAgICByZXR1cm4gbmV3IFUoc3RhdGljX2Nhc3Q8Y29uc3QgVSY+KCpzb3VyY2UpKTsKICAgIH0KICAgIHZpcnR1YWwgdm9pZCBkZXN0cm95KGNvbnN0IFQqIHApIGNvbnN0CiAgICB7CiAgICAgICAgZGVsZXRlIHN0YXRpY19jYXN0PGNvbnN0IFUqPihwKTsKICAgIH0KfTsKfQoKdGVtcGxhdGUgPGNsYXNzIFQ+CmNsYXNzIGNsb25lX3B0cgp7CiAgICBUKiBwdHI7CiAgICBzdGQ6OnNoYXJlZF9wdHI8Y2xvbmVfcHRyX2RldGFpbDo6Y2xvbmVfcHRyX2hlbHBlcl9iYXNlPFQ+PiBwdHJfaGVscGVyOwpwdWJsaWM6CiAgICB0ZW1wbGF0ZSA8Y2xhc3MgVT4KICAgIGV4cGxpY2l0IGNsb25lX3B0cihVKiBwKTogcHRyKHApLCBwdHJfaGVscGVyKG5ldyBjbG9uZV9wdHJfZGV0YWlsOjpjbG9uZV9wdHJfaGVscGVyPFQsIFU+KCkpIHt9CgogICAgY2xvbmVfcHRyKGNvbnN0IGNsb25lX3B0ciYgb3RoZXIpOiBwdHIob3RoZXIucHRyX2hlbHBlci0+Y2xvbmUob3RoZXIucHRyKSksIHB0cl9oZWxwZXIob3RoZXIucHRyX2hlbHBlcikge30KCiAgICBjbG9uZV9wdHImIG9wZXJhdG9yPShjbG9uZV9wdHIgcmh2KQogICAgewogICAgICAgIHN3YXAocmh2KTsKICAgICAgICByZXR1cm4gKnRoaXM7CiAgICB9CiAgICB+Y2xvbmVfcHRyKCkKICAgIHsKICAgICAgICBwdHJfaGVscGVyLT5kZXN0cm95KHB0cik7CiAgICB9CgogICAgVCogZ2V0KCkgY29uc3QgeyAvKmVycm9yIGNoZWNraW5nIGhlcmUqLyByZXR1cm4gcHRyOyB9CiAgICBUJiBvcGVyYXRvciogKCkgY29uc3QgeyByZXR1cm4gKmdldCgpOyB9CiAgICBUKiBvcGVyYXRvci0+ICgpIGNvbnN0IHsgcmV0dXJuIGdldCgpOyB9CgogICAgdm9pZCBzd2FwKGNsb25lX3B0ciYgb3RoZXIpCiAgICB7CiAgICAgICAgc3RkOjpzd2FwKHB0ciwgb3RoZXIucHRyKTsKICAgICAgICBwdHJfaGVscGVyLnN3YXAob3RoZXIucHRyX2hlbHBlcik7CiAgICB9Cn07CgpzdHJ1Y3QgQQp7CiAgICB2aXJ0dWFsIHZvaWQgZm9vKCkgeyBwdXRzKCJBOjpmb28iKTsgfQp9OwoKc3RydWN0IEI6IEEKewogICAgc3RkOjpzdHJpbmcgaWQ7CiAgICBCKGNvbnN0IHN0ZDo6c3RyaW5nJiBpZCk6IGlkKGlkKSB7fQogICAgQihjb25zdCBCJiBvdGhlcik6IGlkKCJDb3B5IG9mICIgKyBvdGhlci5pZCkge30KICAgIH5CKCkgeyBwdXRzKCJ+QiIpOyB9CiAgICB2aXJ0dWFsIHZvaWQgZm9vKCkgeyBwdXRzKGlkLmNfc3RyKCkpOyB9Cn07CgppbnQgbWFpbigpCnsKICAgIGNsb25lX3B0cjxBPiBhKG5ldyBCKCJCX2luc3RhbmNlIikpOwogICAgY2xvbmVfcHRyPEE+IGIoYSk7CiAgICBhLT5mb28oKTsKICAgICgqYikuZm9vKCk7CiAgICBjbG9uZV9wdHI8QT4gYyhuZXcgQSk7CiAgICBhID0gYzsKICAgIGEtPmZvbygpOwp9Cg==
-
upload with new input
-
result: Success time: 0s memory: 2964 kB returned value: 0
B_instance Copy of B_instance ~B A::foo ~B


