When to prefer templated policy based design over non-templated inheritance based design

无人久伴 提交于 2021-02-06 20:43:03

问题


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!"

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

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?


回答1:


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

Runtime vs compile time polymorphism.

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

Performance overhead of virtual calls

Templates generate code that has no indirections

The actual usage of the class.

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

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




回答2:


Depends on the situation I guess... A possible downside of using templates is that the type should be known at compile-time:

HelloWorld<English> hw; // English is plugged at compile-time

In your second example, where you're using a pointer-to-base, this pointer might point to a variety of derived classes. What exactly it points to is not required to be known at compile-time and can therefore be determined by (user-)input at runtime. A possible down-side of this approach is virtual call overhead. In some applications, and on some platforms, this might be unwanted.



来源:https://stackoverflow.com/questions/30596912/when-to-prefer-templated-policy-based-design-over-non-templated-inheritance-base

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!