Yes, this can be done using CRTP .
At first, returning the original pointer obtained from new is very dangerous . In c++ raw pointers should only be used when they do not have ownership of the pointed object. So I took the liberty of using unique_ptr :
struct Base { virtual auto create_obj() -> std::unique_ptr<Base> { return std::unique_ptr<Base>{}; } }; // abstract works too: struct Base { virtual auto create_obj() -> std::unique_ptr<Base> = 0; }; template <class Derived> struct Base_crtp : Base { auto create_obj() -> std::unique_ptr<Base> override /* final */ { return std::unique_ptr<Base>{new Derived{}}; } }; struct D1 : Base_crtp<D1> { }; struct D2 : Base_crtp<D2> { };
And then:
auto b1 = std::unique_ptr<Base>{new D1{}}; auto b2 = std::unique_ptr<Base>{new D2{}}; auto new_d1 = b1->create_obj(); auto new_d2 = b2->create_obj();
bolov
source share