fork download
  1. #include <type_traits>
  2. #include <utility>
  3.  
  4. template< typename T >
  5. class clone_ptr_polymorph
  6. {
  7. void* mDerivedPtr;
  8. T* mBasicPtr;
  9. std::pair<T*, void*> (* mCloner)(void*);
  10.  
  11. template< typename Derived >
  12. static std::pair<T*, void*> clone(void* ptr)
  13. {
  14. auto obj = new Derived{ *reinterpret_cast<Derived*>(ptr) };
  15. return { obj, obj };
  16. }
  17.  
  18. public:
  19. template< typename Derived,
  20. typename=typename std::enable_if<std::is_base_of<T, Derived>::value>::type >
  21. clone_ptr_polymorph( Derived* ptr ) :
  22. mDerivedPtr{ptr},
  23. mBasicPtr{ptr},
  24. mCloner{ &clone<Derived> } {}
  25.  
  26. clone_ptr_polymorph( clone_ptr_polymorph const& p ) :
  27. mCloner{p.mCloner}
  28. {
  29. auto pair = mCloner(p.mDerivedPtr);
  30. mBasicPtr = pair.first;
  31. mDerivedPtr = pair.second;
  32. }
  33.  
  34. ~clone_ptr_polymorph()
  35. {
  36. delete mBasicPtr;
  37. }
  38.  
  39. clone_ptr_polymorph( clone_ptr_polymorph&& ) = default;
  40. clone_ptr_polymorph& operator=( clone_ptr_polymorph&& ) = default;
  41. };
  42.  
  43. template<typename Base,
  44. typename Der,
  45. typename... Args>
  46. clone_ptr_polymorph<Base> make_clone_ptr( Args&&... args )
  47. {
  48. return { new Der(std::forward<Args>(args)...) };
  49. }
  50.  
  51. #include <iostream>
  52.  
  53. struct Base
  54. {
  55. virtual ~Base() { std::cout << "Base-Destructor\n"; }
  56. Base() { std::cout << "Base-Def-Ctor\n"; }
  57. Base(Base const&) { std::cout << "Base-Copy-Ctor\n"; }
  58. Base(Base&&) { std::cout << "Base-Move-Ctor\n"; }
  59. };
  60.  
  61. struct Derived : Base
  62. {
  63. ~Derived() { std::cout << "Derived-Destructor\n"; }
  64. Derived() { std::cout << "Derived-Def-Ctor\n"; }
  65. Derived(Derived const&) { std::cout << "Derived-Copy-Ctor\n"; }
  66. Derived(Derived&&) { std::cout << "Derived-Move-Ctor\n"; }
  67. };
  68.  
  69. int main()
  70. {
  71. auto const& p = make_clone_ptr<Base, Derived>();
  72. auto second = p;
  73. }
  74.  
  75.  
Success #stdin #stdout 0s 3472KB
stdin
Standard input is empty
stdout
Base-Def-Ctor
Derived-Def-Ctor
Base-Def-Ctor
Derived-Copy-Ctor
Derived-Destructor
Base-Destructor
Derived-Destructor
Base-Destructor