何时更喜欢基于模板策略的设计而不是基于非模板继承的设计 [英] When to prefer templated policy based design over non-templated inheritance based design

查看:67
本文介绍了何时更喜欢基于模板策略的设计而不是基于非模板继承的设计的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解使用模板进行基于策略的设计的真正要求.通过 C++ 中的新模板化设计,我发现基于策略的类设计是一种强烈建议的设计方式,它允许您插入"来自策略类的不同行为.一个最小的例子如下(维基的缩短版本):

I am trying to understand the real requirement of the usage of templates for policy based design. Going through the new templated designs in C++ I found that policy based class design is a highly suggested way of design which allows you to 'plug-in' different behaviors from policy classes. A minimal example is the following (a shortened version of the wiki):

template <typename LanguagePolicy>
class HelloWorld : private LanguagePolicy
{
    using LanguagePolicy::message;

public:
    // Behaviour method
    void run() const
    {
        // policy methods
        cout << message();
    }
};

class LanguagePolicyA
{
protected:
    std::string message() const
    {
        return "Hello, World!";
    }
};
//usage
HelloWorld<LanguagePolicyA> hello_worlda;
hello_worlda.run(); // prints "Hello, World!"

快速分析表明,为了获得不同的可插入方法message(),我们继承了模板类型,该类型的定义可由任何人提供(并在编译时识别).

A quick analysis shows that just to get different plugable methods message() we are inheriting from a templated type whose definition can be provided by anyone (and identified at compile time).

但是相同级别的抽象(和可配置的方法)可以在不使用模板代码的情况下通过简单的老式运行时多态实现,如下所示.

But the same level of abstraction (and configurable methods) can be achieved without using a templated code and by the simple old school run time polymorphism as shown below.

class HelloWorld
{
    LanguagePolicy *lp; //list of all plugable class
public:
    HelloWorld(LanguagePolicy *lpn) {
        lp = lpn;
    }

    // Behaviour method
    void run() const
    {
        // policy methods
        cout << lp->message();
    }
};
class LanguagePolicy
{
protected:
    virtual std::string message() const;
};

class LanguagePolicyA: LanguagePolicy
{
protected:
    std::string message() const
    {
        return "Hello, World!";
    }
};
//usage
HelloWorld helloworld(new LanguagePolicyA);
helloworld.run();

功能和抽象级别我看不出这两种方法有太大区别(即使第二种方法为 LanguagePolicy 增加了几行额外的代码,我认为它是必要的其他用户了解界面;否则了解 LanguagePolicy 取决于文档).但我确实认为后者是干净的"(来自没有经常使用模板的人).这是因为我个人认为非模板化的类更易于查看和理解.一个非常好的例子是流行的库 VTK(可视化工具包),它使用第二种方法解决了许多不同的问题.即使没有大量的 VTK 文档,我们大多数人——它的用户,只要看看它的类图(有时它们非常大)并推断出类的行为;并在我们的应用程序中开发高度可配置和复杂的管道(不能将 VTK 成像为基于模板:)).相反的是像 STL/BOOST 这样的库,我认为任何人都不可能在不使用大量文档的情况下识别类的工作.

Functionality and level of abstraction wise I don't see much of a difference in the two approach (even though the second approach has few extra lines of code for LanguagePolicy, I think it is needed for the other users to know the interface; otherwise understanding LanguagePolicy depends upon the documentation). But I do think the later to be 'clean' (coming from someone who has not used template much). This is because personally in my opinion non-templated classes are cleaner to look at and understand. An extremely good example is the popular library VTK (Visualization Tool Kit) which solves many different problems using the second approach. Even though there are not extensive documentations of VTK, most of us - its users, can just have a look into its class diagrams (sometimes they are quite big) and deduce behaviors of classes; and develop highly configurable and complicated pipelines in our application (can't imaging VTK to be template based :)). The opposite is libraries like STL/BOOST which I don't think is possible for anyone to be able to identify the working of the classes without the use of extensive documentation.

所以我的问题是,基于模板的策略设计真的比基于虚拟继承的设计优越吗(仅在这种基于策略的设计场景中)?如果是这样,什么时候以及为什么?

So my question is, is the template based policy design really superior (only in this scenario of policy based design) than virtual inheritance based? If so, when and why?

推荐答案

两者都是有效的结构化方式,实际上取决于需求.例如

Both are valid ways of structuring, it actually depends on the requirements. E.g.

运行时与编译时多态性.

你什么时候想要/可以/必须实现多态?

When do you want/can/have to achieve polymorphism ?

虚拟调用的性能开销

模板生成没有间接引用的代码

Templates generate code that has no indirections

类的实际使用.

当你必须存储异构集合时,需要一个基类,所以你必须使用继承.

When you have to store heterogenous collections, a base class is needed, so you have to use inheritance.

一本关于基于策略的设计的非常好的书(有点过时但很好)是 现代 C++ 设计

A very good book on policy-based design (a bit dated but good nevertheless) is Modern C++ Design

这篇关于何时更喜欢基于模板策略的设计而不是基于非模板继承的设计的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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