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;”的操作;问题是我不想丢失类型。