c++ - 通过模板多重继承

标签 c++ templates inheritance multiple-inheritance diamond-problem

<分区>

将虚拟多重继承(钻石)替换为模板继承(线性)是个好主意吗?例如我有这个类图:

       IBase
    /          \
   /            \
IExtendedBase  BaseImpl
  \            /
   ExtendedImpl

我知道我可以用虚拟继承来实现它。但是我可以使用模板来使这个图表线性化吗?

class IBase
    {
    public:
        virtual std::string name() = 0;
    };

    template<typename T>
    class BaseImpl : public T
    {
    public:
        virtual std::string name() override
        {
            return "BaseCommonImpl";
        }
    };

    template<typename T>
    class IExtendedBase : public T
    {
    public:
        virtual std::string extended_name() = 0;
    };

    template<typename T>
    class ExtendedBaseImpl : public T
    {
    public:
        virtual std::string extended_name() override
        {
            return "ExtendedBaseImpl";
        }
    };

现在有了 typedef,我可以特化 ExtendedBase

typedef IExtendedBase<BaseImpl<IBase>> _ExtendedBase;
typedef ExtendedBaseImpl<_ExtendedBase> _ExtendedBaseImpl;

哪种方法更好?虚拟继承还是模板继承?

最佳答案

虽然您可以使用这两种不同的方法(多重继承与模板)获得类似的结果,但在语义上存在重要差异。

很遗憾,您没有提供足够的信息来推荐一个客观的选择。所以这里有一些注意事项:

多重继承方式

多重继承是为了强制执行有效的 separation of concerns

如果在您的情况下,应该首选这种方法 ExtendedImpl 是一个 IExtendBase并同时 is-a BaseImpl , 但两者的继承关系是独立的。

在某些情况下(例如转换),它会带来轻微的性能开销。

但它的优点是允许您的 ExtendedImpl在可以使用其任何基地的地方使用。此外,它允许动态的、基于运行时的多态性(如果它的任何一个基类有一个虚拟成员函数)。

enter image description here

模板方法

模板用于通用编程。如果您的 ExtendedImpl 优先使用此方法确实是通用的,“基础”是您通用概念的更多参数,而不是进一步扩展的概念。

Template 在这里会采用性能稍好(单继承)的方法。但是您没有实现初始模式的原始概念。而且您没有动态多态性的灵 active 。

enter image description here

如果类型之间的关系不具有通用性,您可能会在此处引入不需要的依赖关系。例如这里,IExtendedBase 将继承自 BaseImpl。在许多情况下这可能没问题。但在其他情况下,这可能完全不自然,导致维护阶段出现持久的设计问题。

结论

现在由您决定哪种优势和不便最适合您的具体情况。如果需要,您可以编辑您的问题,更准确地说明上下文和您的意图,我会调整答案 因此。

关于c++ - 通过模板多重继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30122645/

相关文章:

c++ - 在 C++ Builder XE8 中从/向某些组合框显示/添加项目

c++ - 如何将模板化的结构/类声明为 friend ?

c# - 从各种 List<衍生类 <T>> 创建 List<genericBaseClass<T>>

c++ - 在不失去对其构造函数的访问的情况下稍微派生一个类

C++ 字符串操作/输入

c++ - 缺少运算符 << 但它在那里

ruby-on-rails - 如何从 Controller 中包含的模块渲染js模板?

c++ - 虚拟继承是如何工作的?

delphi - 为什么在重载基类中引入的抽象方法时编译器会发出警告?

c++ - 在 CPP 运行时选择随机数生成器