I have a Base class which contains a member variable std::unique_ptr< Base > next. I have several derived classes of Base.
I have a non-virtual function Base::grow() which initialises next. next will always point to an object of the type of the object calling grow.
That next is of the correct type is guaranteed via a virtual function call within Base::grow().
Creating a virtual function for each derived class is cumbersome and bug prone, hence my question: can I do this more succintly ?
My current minimal working example looks like this:
#include <iostream>
#include <memory>
class Base{
public:
static const unsigned SIZE = 3;
std::unique_ptr<Base> next;
void grow(unsigned index){
if (index < SIZE){
print();
next = get_new();
next.get()->grow(index + 1);
}
}
virtual std::unique_ptr<Base> get_new(){
return std::unique_ptr<Base>(new Base());
//return std::move(std::unique_ptr<Base>(new Base())); (move not nec. see comments)
}
virtual void print (){
std::cout << "a Base ";
}
};
class Derived: public Base{
public:
virtual void print (){
std::cout << "a Derived ";
}
virtual std::unique_ptr<Base> get_new(){
return std::unique_ptr<Base>(new Derived());
}
};
int main(){
std::unique_ptr<Base> b;
b = std::unique_ptr<Base> (new Base());
b->grow(0);
std::unique_ptr<Base> c;
c = std::unique_ptr<Base> (new Derived());
c->grow(0);
}
Output is correct : a Base a Base a Base a Derived a Derived a Derived
In summary: I'd like a solution which does away tedious get_new, I would like Base::grow to determine what type to create based on type of calling object. I've considered using decltype, but without success.
Code snippet related to attempt to determine type at run-time:
typedef std::remove_reference<decltype(*this)>::type DynamicBase;
next = std::unique_ptr<DynamicBase>(new DynamicBase());
DynamicBase above is always determined to be Base, even when this
is pointer to Derived
What you want is impossible: you need at least one virtual function call, ie a virtual method overridden in every derived. Consider, for example, the situation that the derived class is defined in another compilation unit. How shall the code for the base class obtain a new derived object of unknown type if not using polymorphism?
Yesterday I came across the Curiously Recurring Template Pattern (crtp) for the first time and I'm fairly sure that it can be used to such that get_new
is only defined once.
The idea of crtp is well explained here: https://katyscode.wordpress.com/2013/08/22/c-polymorphic-cloning-and-the-crtp-curiously-recurring-template-pattern/
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.