在C ++中流畅的接口和继承 [英] Fluent interfaces and inheritance in C++

查看:94
本文介绍了在C ++中流畅的接口和继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想建立一个基础(抽象)类(让我们称之为 type :: base )具有一些常见的功能和流畅的接口, m面向是所有这些方法的返回类型

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();
 }

这不会编译,因为我们返回base而不是my_type。

This won't compile because we're returning base instead of my_type.

我知道我可以:

 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?

推荐答案

这种丢失类型的问题可以通过模板来解决 - 但它相当复杂

This problem of "losing the type" can be solved with templates - but it's rather complicated.

例如

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>

另一种方法可能不是对对象使用流畅接口,而是使用指针:

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;
  }
};

使用这样:

FluentPizzaPtr<SquarePizza> squarePizzaFactory() { ... }

FluentPizzaPtr<SquarePizza> myPizza=squarePizzaFactory().withAnchovies();

这篇关于在C ++中流畅的接口和继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆