【问题标题】:Extending a template class while fixing the template parameter在修复模板参数的同时扩展模板类
【发布时间】:2012-12-05 12:08:41
【问题描述】:

我已经定义了一个类

template <class T> class NodeMap {

NodeMap(int n, T defaultEntry = NULL);

virtual ~NodeMap();

T& operator[](const node& u);

...

}

node 类型的对象映射到T 参数类型的对象。

现在我想要一个课程Matching,它本质上是一个NodeMap&lt;node&gt;。为方便起见,我想添加isProperMatching(Graph&amp; G)match(node u, node v) 之类的方法。 Matching 可以继承 NodeMap&lt;node&gt; 吗?是否可以(如果可以,这是一个好主意)扩展具有固定模板参数的模板类吗?

【问题讨论】:

  • 这很好。 NodeMap&lt;node&gt; 是一个完全正常的类,只是它的名字拼写有点奇怪。

标签: c++ oop templates inheritance


【解决方案1】:

就您显示的代码告诉我您在做什么而言,您有以下可能性:

  1. Nodemap 专用于T=node,以包含您想要的其他方法。为方便起见,您可以键入def Nodemap&lt;node&gt;Matching。但是,这可能会添加您在非专业模板中的方法的一些代码重复。
  2. 按照您的建议从Nodemap&lt;node&gt; 派生。如果您设计Nodemap 使其成为适当的基类,这是一种有效的方法。虚拟析构函数建议您已经这样做了,尽管可能根本不需要将方法设为虚拟。
  3. 如果可能,将附加功能作为免费功能提供,因此无需派生或专门化Nodemap&lt;node&gt;

我会考虑前两种的混合方法:制作一个包含NodeMaps 和Matching 的通用功能的基类模板(我称之为NodeMapBase),然后派生NodeMap模板来自相应的基类模板(可能没有添加太多功能)并从NodeMapBase&lt;node&gt; 派生Matching。如果您查看 MSVC 的标准库实现,就会发现很多。

【讨论】:

  • 拥有一个公共基类NodeMapBase 有什么好处?目前,我将Matching 视为具有附加功能的NodeMap&lt;node&gt;,因此我不清楚引入另一个基类的好处。
  • 如果您看不到任何好处,请不要使用它。有时这是一个可行的选择,例如如果Matching 需要NodeMap 不提供的基类构造函数,那么您可以在基类中提供该构造函数。在这种情况下,继承是一种避免代码重复的纯技术方式,而不是表达真正的“is-a”关系。
【解决方案2】:

是的,很常用。

class Matching : public NodeMap<node> {
    ...
};

【讨论】:

    【解决方案3】:

    这取决于Matching 的界面应该是什么样子。如果你想提供完全相同的方法加上一些方便的方法,你可以继承它

    class Matching : public NodeMap<node> {...};
    

    但如果Matching 不是NodeMap&lt;node&gt;,即提供不同的接口,则只能将其用作聚合

    class Matching {
    private:
        NodeMap<node> matchingNodes;
    public:
        // public interface of Matching
        bool isProperMatching(Graph& G);
        bool match(node u, node v);
        ...
    };
    

    顺便说一句,此建议与 NodeMap 是否为模板无关。

    【讨论】:

      猜你喜欢
      • 2014-04-12
      • 2014-12-17
      • 2012-03-27
      • 2015-05-19
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多