Fluent interfaces and inheritance in C++
c++, fluent-interface, inheritance
Solution
This problem of "losing the type" can be solved with templates - but it's rather complicated.
Eg.
class Pizza
{
string topping;
public:
virtual double price() const;
};
template <class T, class Base>
class FluentPizza : public Base
{
T* withAnchovies() { ... some implementation ... };
};
class RectPizza : public FluentPizza<RectPizza, Pizza>
{
double price() const { return length*width; :) }
};
class SquarePizza : public FluentPizza<SquarePizza, RectPizza>
{
... something else ...
};
You can then write
SquarePizza* p=(new SquarePizza)->withAnchovies();
The pattern is that instead of
class T : public B
you write
class T : public Fluent<T, B>
Another approach could be not to use fluent interface on the objects, but on pointers instead:
class Pizza { ... };
class RectPizza { ... };
class SquarePizza { ... whatever you might imagine ... };
template <class T>
class FluentPizzaPtr
{
T* pizza;
public:
FluentPizzaPtr withAnchovies() {
pizza->addAnchovies(); // a nonfluent method
return *this;
}
};
Use like this:
FluentPizzaPtr<SquarePizza> squarePizzaFactory() { ... }
FluentPizzaPtr<SquarePizza> myPizza=squarePizzaFactory().withAnchovies();
Problem
I'd like to build a base (abstract) class (let's call it `type::base`) with some common funcionality and a fluent interface, the problem I'm facing is the return type of all those methods ``` class base { public: base(); virtual ~base(); base& with_foo(); base& with_bar(); protected: // whatever... }; ``` Now I could make subtypes, e.g.: ``` class my_type : public base { public: myType(); // more methods... }; ``` The problem comes when using those subtypes like this: ``` my_type build_my_type() { return my_type().with_foo().with_bar(); } ``` This won't compile because we're returning base instead of my_type. I know that I could just: ``` my_type build_my_type() { my_type ret; ret.with_foo().with_bar(); return ret; } ``` But I was thinking how can I implement it, and I've not found any valid ideas, some suggestion?