Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C+中流畅的接口和继承+;_C++_Inheritance_Fluent Interface - Fatal编程技术网

C++ C+中流畅的接口和继承+;

C++ C+中流畅的接口和继承+;,c++,inheritance,fluent-interface,C++,Inheritance,Fluent Interface,我想构建一个基本(抽象)类(我们称之为type::base),它具有一些常见的函数性和流畅的接口,我面临的问题是所有这些方法的返回类型 class base { public: base(); virtual ~base(); base& with_foo(); base& with_bar(); protected: // whatever... }; 现在我可以创建子类型,例如:

我想构建一个基本(抽象)类(我们称之为
type::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();
 }
return *static_cast<my_type*>(&my_type().with_foo().with_bar());
FluentPizzaPtr<SquarePizza> squarePizzaFactory() { ... }

FluentPizzaPtr<SquarePizza> myPizza=squarePizzaFactory().withAnchovies();
这不会编译,因为我们返回的是base而不是my_类型

我知道我可以:

 my_type build_my_type()
 {
    my_type ret;
    ret.with_foo().with_bar();

    return ret;
 }

但是我在想我怎样才能实现它,我没有找到任何有效的想法,一些建议?< /P> < P>我在C++中这样做,我相信它也将在C++中工作,就是提供一个默认的代码实现。请原谅我的错误,但是:


<>在C++中,你应该重新定义指针或引用而不是值。此外,您可能需要解释“流畅的界面”的含义。

一种解决方案的工作原理如下:

 my_type build_my_type()
 {
    return my_type().with_foo().with_bar();
 }
return *static_cast<my_type*>(&my_type().with_foo().with_bar());
FluentPizzaPtr<SquarePizza> squarePizzaFactory() { ... }

FluentPizzaPtr<SquarePizza> myPizza=squarePizzaFactory().withAnchovies();
return*static_cast(&my_type().with_foo().with_bar());
使用
static\u cast
基本上告诉编译器“我知道我在这里做什么”。

这个“丢失类型”的问题可以通过模板解决,但它相当复杂

例如

模式是,而不是

class T : public B
你写

class T : public Fluent<T, B>
T类:公共语言
另一种方法可能不是在对象上使用fluent接口,而是在指针上使用:

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;
  }
};
classpizza{…};
类{…};
全班同学{…不管你怎么想…};
模板
班机
{
比萨饼;
公众:
凤尾鱼丰盛比萨(){
pizza->addAnchovies();//非流质方法
归还*这个;
}
};
这样使用:

 my_type build_my_type()
 {
    return my_type().with_foo().with_bar();
 }
return *static_cast<my_type*>(&my_type().with_foo().with_bar());
FluentPizzaPtr<SquarePizza> squarePizzaFactory() { ... }

FluentPizzaPtr<SquarePizza> myPizza=squarePizzaFactory().withAnchovies();
FluentPizzaPtr squarePizzaFactory(){…}
FluentPizzaPtr myPizza=squarePizzaFactory()。带凤尾鱼();

您应该返回引用/指针,并且不需要保留类型信息

class base {
  public:
     base();
     virtual ~base();

     base &with_foo();
     base &with_bar();
  protected:
     // whatever...
};

class my_type : public base {
  public:
    my_type();        
    // more methods...
};

base *build_my_type()
{
   return &new my_type()->with_foo().with_bar();
}

您已经有了一个虚拟析构函数。您可能还有其他虚拟功能。通过基类型和其中声明的虚拟函数访问所有内容。

我删除了名称空间内容,因为它与问题无关(据我所知),但这并不能解决问题-问题是类型不匹配,这与问题无关。抱歉-我一看到名称“Martin”我的bullsh*t探测器在满音量时发出声音,我再也看不清了。名字和姓氏似乎都不重要。你能举个例子吗?这可能很有趣。编辑。这可能很有趣,但我不知道我个人是否会使用它…所以你实际上会切换到指针。然后,您可以只使用简单的多态性,而不使用CRTP,并返回base*。您可以在那里想象引用(如果您不需要指针)。我只是不想让这些方法总是返回一个副本,但这不是核心问题。CRTP的要点是消除对base(或base*,或base&)的衰减,这是我认为您希望避免的。如果您返回指针或引用,请返回静态\u转换(this)或静态\u转换(this)(如果您不介意更改原件的话,后者也适用于副本。如果您希望返回副本并保持原件完整,请执行类似“t ret=*(t)this;do_some_with_ret;return ret;”的操作;问题是我不想丢失类型。