我最近正在为一个侧面项目(cpp-markdown
图书馆,好奇的)编写一段C++代码,并遇到了一个我想要一些意见的编码问题.
cpp-markdown
有一个名为的基类Token
,它有许多子类.主要亚类中的两个是Container
(其保持其它的集合Token
或多个)和TextHolder
(用作基类Token
包含当然文本,S).
大多数处理都是通过虚函数处理的,但有些处理在单个函数中处理得更好.对于这一点,我结束了使用dynamic_cast
,以向下转换从指针Token*
到它的一个子类,所以我可以调用特定于子类和它的子类的功能.铸造不可能失败,因为代码能够通过虚函数(例如isUnmatchedOpenMarker
)来判断何时需要这样的东西.
我还有两种方法可以解决这个问题:
创建我想要作为虚函数调用的所有函数Token
,并为每个子类留下一个空体,除了需要处理它们的子类,或者......
创建一个虚函数,Token
该函数将返回正确类型的指针,指向this
在某些子类型上调用它时,如果在其他任何子类型上调用则返回空指针.基本上是我已经在那里使用的虚拟功能系统的扩展.
对我来说,第二种方法似乎比现有方法和第一种方法都要好.但我想知道其他有经验的C++开发人员对它的看法.或者我是否担心过多的琐事.:-)
#1污染类名称空间和vtable以查找不需要它的对象.好的,当你有一些通常会实现的方法时,但只有一个派生类需要时才显得丑陋.
#2只是dynamic_cast<>
一件波尔卡圆点连衣裙和口红.不会使客户端代码更简单,并且纠缠整个层次结构,要求基类和每个派生类对每个其他派生类都是半知晓的.
只是用dynamic_cast<>
.这就是它的用途.
如果你想变得聪明,你也可以构建一个双重调度模式,这是访问者模式的三分之二.
创建TokenVisitor
包含空虚visit(SpecificToken*)
方法的基类.
accept(TokenVisitor*)
向Token 添加一个虚拟方法,该方法在传递的TokenVisitor上调用正确类型的方法.
从TokenVisitor中获取您需要以不同方式对所有令牌执行的各种操作.
对于对树结构有用的完整访问者模式,使用默认accept
方法迭代调用token->accept(this);
每个访问者的子项.