为啥不抽象政策?
Posted
技术标签:
【中文标题】为啥不抽象政策?【英文标题】:Why not abstract policies?为什么不抽象政策? 【发布时间】:2012-03-10 02:08:44 【问题描述】:在实施政策时,需要遵循特定的界面。据我了解,这些政策必须能够相互替代。在现代 c++ 书中,Ch 1.5 3 策略具有相同的接口“T* Create() ”。为什么不需要抽象它。如果策略应该有许多接口,这将是很重要的。据我了解,抽象类给出了哪些接口应该在具体类(策略类)中的方法。在Wikipedia example“using”中定义了策略应该有哪些接口,但它不是通过抽象类。抽象类的目的不是确保派生类具有所需的接口吗?
我错过了什么?
【问题讨论】:
【参考方案1】:不同之处在于使用抽象基类的接口具有提供运行时多态性的虚函数。
这些策略用于为模板提供编译时多态性。编译器会注意到您的策略类是否有T* Create()
。如果没有,在尝试使用时会出现编译时错误。
【讨论】:
【参考方案2】:我从未在实践中真正使用过基于策略的设计,而且自从我用 C++ 编写代码以来,它已经很长时间了,但这是我的解释。正如您所指出的,主机类可以通过接口或通过类似 wiki 示例描述的 using output_policy::Print;
之类的方式对使用的策略实施约束。
using 方法的一个优点(或不同之处)是它的主动限制较少且不那么严格,因为策略具有隐含的契约,该契约直接由使用它们的代码表示。在使用示例中,给定代码的当前状态,output_policy 实现只需要实现一个名为 Print 的方法,该方法返回任何内容并接受 language_policy::Message() 返回的任何内容(在这种情况下,所有 language_policies 返回一个 std::string) .这更接近于鸭子打字。
一个缺点是,一旦代码消失,隐含的合同就会消失。另一个缺点是策略之间存在一定程度的依赖关系。作为一个非常人为的例子,如果一个 output_policy 有一个只打印字符串的非泛型 Print 方法,它就不能与只打印整数的 language_policy 一起使用。
我不明白为什么您不能在需要时添加策略接口。一个示例是 HelloWorld 类可能想要约束 output_policy 以便它打印字符串而不是其他任何内容。您可以通过编写如下代码来实现这一点 - 请注意,您必须使用 SFINAE 来强制 output_policy<std::string>
实际实现 OutputPolicyInterface<std::string>
。
template<typename message_type>
class OutputPolicyInterface
virtual void Print( message_type message ) = 0;
;
template <template<class> class output_policy, typename language_policy>
class HelloWorld : public output_policy<std::string>, public language_policy
public:
void Run()
Print( Message() );
//Print(2); won't work anymore
;
【讨论】:
以上是关于为啥不抽象政策?的主要内容,如果未能解决你的问题,请参考以下文章