C++ OO设计:模板参数的继承

cfa*_*771 14 c++ oop inheritance templates

我有一个继承链,Base是基类.我希望能够编写一个继承Base和另一个Base派生类的类模板.我可以使用虚拟继承,但我发现了另一种解决方案.我想知道它是否是普通/相当/合法的类设计:

编写一个类模板,其中模板参数是从中派生的类,即它必须是Base或Base派生类.在构造函数中,我可以使用静态断言来确保用户不使用任何非法类作为模板参数.

如果它工作,我将永远不会有虚拟继承问题...问题是,它可以做到这一点.我从未在其他项目中看到它,所以我想在使用它之前确定它.

编辑:只是为了确保我不要混淆你,这里有一些代码:

class Base
{
};

class Derived : public Base
{
};

template <Class TheBase>
class MyDerived : public TheBase
{
};
Run Code Online (Sandbox Code Playgroud)

现在我可以使用Base或任何Base衍生的类,例如Derived,作为TheBase参数.

Dan*_*ler 23

这是一种有效的设计模式.它是mixin继承,而不是CRTP.Mixin继承提供了一种方法来由程序员手动线性化继承层次结构来安全地模拟多重继承.模板类是mixins.如果你想扩展一个包含多个mixin的类,你必须决定组合的顺序Big<Friendly<Dog> >.在Dobb博士的文章中描述了C++中的Mixin编程.混入可以被用来实现静态版本GoF的Decorator模式的描述在这里.Mixins在C++中扮演一个角色,在Scala和SmallTalk中扮演特征(而不是C++特征).

CRTP中,它是作为模板的基类:

template <class Param>
class Base { ... };

class Derived : public Base<Derived> { ... };
Run Code Online (Sandbox Code Playgroud)


Ed *_*rbu 10

后来编辑:一年后,我在这里修改自己的答案.我最初错误地说OP发布的模式是CRTP.这是不正确的.这确实是一个混音,请阅读Daniel Mahler在页面下方的答案,以获得正确的解释.

原文:可以使用这样的设计.例如,WTL使用它.它用于实现静态多态性,被称为奇怪的重复模板模式

  • 不完全是CRTP,但仍然有用。例如,选择可替换的接口非常有用。 (2认同)

Moo*_*ice 8

正如扎迪里昂指出的那样,这很好.它的工作原理(简化)是C++中的模板,与C#中的泛型不同,是编译时的.说"这是一个类型的定义"对我来说是错误的,而且我会为它做出很多抨击,但让我们保持简单并说它是.

考虑:

class base {
protected:
    base() { };
    virtual ~base() { };
};

template<class T>
class super : public T {
};
Run Code Online (Sandbox Code Playgroud)

然后:

super<base> s;
Run Code Online (Sandbox Code Playgroud)

绝对没问题.这实际上是一个相当漂亮的结构.因为它是编译时,你可以选择你的基类,在某些设计习语中可能非常有利.

  • +1比我更详细一点.我想补充一点,当你需要编写一些可重用的代码作为人们可以派生的基类时,这是一个非常有用的模式,但是有些代码无法使用某些类型的派生类进行操作.在这种情况下,可以在基类中使用模式来确定派生类型具有哪些属性(例如std :: is_base_of),并在满足某些条件时启用某些代码. (2认同)

mey*_*mer 5

这是一个很好的座右铭:对类型使用模板,但对行为继承.

坚持下去.你可能会使用很多捷径/技巧来完成工作,但从长远来看,这些糟糕的设计选择将令人头疼.如果您想使用此类产品,请务必研究其优缺点.

现在,回到你的问题,你问的可能是做什么:参见CRTP静态多态.