c++ - 我有这两个相似的类(class)。您将使用什么设计来分解代码?

标签 c++ templates inheritance code-duplication

<分区>

我有一个非常复杂的图形数据结构。为了清楚起见,让我们将其简化为:

class Node;
class AbstractEdge { void foo() {} };
class Edge1: public AbstractEdge { void bar1() {} };
class Edge2: public AbstractEdge { void bar2() {} };

如您所见,我们的图与其他图不同:存在两种边,均继承自 AbstractEdge。此设计无法更改。现在,假设我必须按照以下方式设计两个类:

class OrientedEdge1
{
  Edge1 * edge;
  bool orientation;

  void foo() { edge->foo(); } 
  void bar1() { edge->bar1(); }
}

class OrientedEdge2
{
  Edge2 * edge;
  bool orientation;

  void foo() { edge->foo(); }
  void bar2() { edge->bar2(); }
}

在实践中,OrientedEdge1::foo() 和 OrientedEdge2::foo() 比仅调用单个方法要长得多,但想法是它们是相同的,仅调用从 AbstractEdge 继承的方法。

您会使用什么设计来分解代码?我正在考虑三种方法:

1。使用免费功能

foo_impl(AbstractEdge * edge) { edge->foo(); }

class OrientedEdge1
{
  Edge1 * edge;
  bool orientation;

  void foo() { foo_impl(edge); }
  void bar1() { edge->bar1(); }
}

class OrientedEdge2
{
  Edge2 * edge;
  bool orientation;

  void foo() { foo_impl(edge); }
  void bar2() { edge->bar2(); }
}

优点:

  • 非常简单的解决方案,比根本不分解要好得多。

缺点:

  • 并非所有方法都可以作为自由函数实现。

  • 声明代码仍然重复。

2。使用继承

class AbstractOrientedEdge
{
  AbstractEdge * edge;
  bool orientation;

  void foo() { edge->foo(); }
}

class OrientedEdge1: public AbstractOrientedEdge
{
  Egde1 * edge1() { return static_cast<Egde1*>(edge); }

  void bar1() { edge1()->bar1(); }
}

class OrientedEdge2: public AbstractOrientedEdge
{
  Egde2 * edge2() { return static_cast<Egde2*>(edge); }

  void bar2() { edge2()->bar2(); }
}

优点:

  • 更多分解。

  • 我不打算以多态方式使用这两个类,但谁知道呢,也许它们通过继承相关的事实在将来会变得有用。

缺点:

  • 在构造函数/setter 中需要注意强制 OrientedEdge1::edge 始终指向 Egde1*。

  • 不知何故,static_cast 感觉不对。

3。使用模板

template <class EdgeT>
class OrientedEdge
{
  EdgeT * edge;
  bool orientation;

  void foo() { edge->foo(); }
}

class OrientedEdge1: public OrientedEdge<Edge1>
{
  void bar1() { edge->bar1(); }
}

class OrientedEdge2: public OrientedEdge<Edge2>
{
  void bar2() { edge->bar2(); }
}

优点:

  • 大多数分解。

  • 存储在两个类中的指针具有正确的类型,无需转换。

缺点:

  • 需要在 header 中保留共享代码的实现,这会强制包含 AbstractEdge.h(可以通过以前的方法的前向声明来避免)。

问题:您倾向于使用哪种方法?您还有其他解决方案或建议吗?

最佳答案

1 和 3。

3 删除重复的样板文件,1 将实现移动到我想要的任何地方。

关于c++ - 我有这两个相似的类(class)。您将使用什么设计来分解代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27285772/

相关文章:

c++ - 类模板的静态方法的奇怪问题

java - 实例变量隐藏继承

c++ - 关于不同类型继承的思考

c++ - 如何使用 GraphicsMagick C++ API 找到 PNG 图像的大小?

c++ - 为什么在没有参数的情况下调用省略号而不是可变参数模板?

c++ - 创建基于模板和 boost::shared_ptr 的通用工厂时出现编译错误

java - 没有基类访问的 hibernate 字段继承

Python 模拟 C++ 指向类成员的指针

c++ - 用两点映射一维数组

c++ - 读取文件的二进制内容并在 C++ 中反转其内容