【问题标题】:C++: Avoiding dual maintenance in inheritance hierarchiesC++:避免​​继承层次结构中的双重维护
【发布时间】:2011-01-22 11:23:25
【问题描述】:

在创建 C++ 继承结构时,必须在多个地方定义完全相同的成员函数:

如果 B 是一个抽象基类,并且 D、E 和 F 都继承自 B,你可能会有这样的情况:

class B
{
   virtual func A( ... params ) = 0;
};

class D : public B
{
   func A( ... params );
};

/* ... etc... similar implementations for E and F */

所以,这里显然有些重复。如果到B的接口很大,如果接口需要改变,你可能有很多地方需要改变。

一位同事建议使用巧妙创建的嵌入式#includes 进行一些技巧,ala:

class D: public B
{
   #include "B_Interface.h"  // B_Interface.h is a specially crafted .h file
}

这似乎有点笨拙?是吗?有没有更好的解决方案来避免双重维护?

另外,也许这里的解决方案真的是更好的支持语言的工具,比如 Visual Assist X?

编辑:假设派生类必须具有唯一的实现。

【问题讨论】:

  • Boost 库实际上在某些部分做到了这一点,虽然不是为了继承,只是为了代码重用。
  • 为什么不使用宏而不是包含?关键是性能方面的#include 意味着在符号表中已经存在宏时查找文件。

标签: c++ dry base-class


【解决方案1】:

实际上,更改接口的最大问题通常是使用它的所有代码,而不是实现它的代码。如果对于实施者来说很容易改变它,它可能会让用户的生活变得更加困难。

【讨论】:

  • 同意 -- 恕我直言,界面应该尽可能少地改变,所以如果这很痛苦,那是一件好事!
【解决方案2】:

改变一个广泛使用的界面是痛苦的不是错误;这是一个功能。

【讨论】:

    【解决方案3】:

    另外,也许这里的解决方案真的是更好的支持语言的工具,比如 Visual Assist X?

    没错。更改方法签名是key feature 的重构工具。

    【讨论】:

    • 我支持这个建议。如果你必须重构 C++ 代码,我发现 VAX 相当不错。 (而且我发现它还不错,还有很多其他原因。)
    【解决方案4】:

    如果您必须使用一些默认行为一遍又一遍地实现它们,那么它们可能应该只是虚拟的,而不是纯虚拟的。

    【讨论】:

    • 在我的特殊情况下,每个派生类都有不同的实现。
    【解决方案5】:

    与其将预处理器用于另一种不应该使用的方式,我会尝试我的编辑器(或 IDE,如果你喜欢的话。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-16
      • 2014-12-22
      • 1970-01-01
      • 2011-06-16
      • 1970-01-01
      • 1970-01-01
      • 2012-01-23
      • 1970-01-01
      相关资源
      最近更新 更多