我想用一些常见的功能和流畅的接口构建一个基类(抽象)类(让我们称之为类型:: base),我面临的问题是所有这些方法的返回类型
class base { public: base(); virtual ~base(); base& with_foo(); base& with_bar(); protected: // whatever... };
现在我可以制作亚型,例如:
class my_type : public base { public: myType(); // more methods... };
使用这样的子类型时会出现问题:
my_type build_my_type() { return my_type().with_foo().with_bar(); }
这将无法编译,因为我们正在返回base而不是my_type.
我知道我可以:
my_type build_my_type() { my_type ret; ret.with_foo().with_bar(); return ret; }
但我在想如何实现它,我没有找到任何有效的想法,一些建议?
解决方法
这种“失去类型”的问题可以通过模板解决 – 但它相当复杂.
例如.
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 ... };
然后你可以写
SquarePizza* p=(new SquarePizza)->withAnchovies();
模式是而不是
class T : public B
你写
class T : public Fluent<T,B>
另一种方法可能不是在对象上使用流畅的接口,而是在指针上使用:
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; } };
使用这样:
FluentPizzaPtr<SquarePizza> squarePizzaFactory() { ... } FluentPizzaPtr<SquarePizza> myPizza=squarePizzaFactory().withAnchovies();