C :基类调用自己的虚拟函数 - 一个反图案
C++: Base class calling own virtual function - an anti-pattern?
我看到了类似于以下常用的模式。我们有一个可以完成大部分工作的基类,但是称其自己的虚拟/纯虚拟函数之一来完成作业的一部分,而每种派生类型都不同。一个人为的例子:
struct PacketProcessor {
virtual void parseEncap(pkt) = 0;
void process(Pkt pkt)
{
parseEncap(pkt); // Calls its own virtual function to parse the encap
processFurther(pkt);
...
}
};
我们创建派生类,该类将覆盖虚拟函数并提供特定于派生类的功能。
struct EthernetProcessor : public PacketProcessor {
void parseEncap(Pkt) override { // parse ethernet encap}
};
struct PPPProcessor : public PacketProcessor {
void parseEncap(Pkt) override { //parse ppp encap }
};
但是,随着时间的流逝,我会感觉到这种模式,基础类中越来越多的功能被虚拟化或在随机位置添加并调用更多虚拟函数,以腾出空间,以实现不同的派生类行为。
[在现实生活代码中,我看到了一个add((和add_extra((虚拟函数:-)
随着时间的流逝,由于每种类型的处理方式完全不同。即使共同的基类也给出了一个错误的概念。但是,是的,它仍然保留针对不同类型的代码,而不是(type1(/else(type2(。
。实现类似事物的另一种方法是将差异分为不同的类(层次结构(,并在其中调用虚拟函数。这对于EG也很常见:
struct Encap {
virtual void parseEncap(Pkt) = 0;
};
struct EthernetEncap : public Encap {
void parseEncap(Pkt pkt) {}
};
struct PPPEncap : public Encap {
void parseEncap(Pkt pkt) {}
};
struct PacketProcessor {
PacketProcessor(Encap *encap) : m_encap{encap} {}
void process(Pkt pkt)
{
m_encap->parseEncap(pkt);
processFurther(pkt);
...
}
private:
EncapPtr m_encap;
};
,但在这种情况下,也可以添加封装类。否则会有太多的组件类,例如封装提供不同的功能。
,但好事是,PacketProcessor将遵循所有类型的封装的特定路径。另外,这种方法不像以前的图案那样灵活,因为我们需要将所有封装都放入一个非常特定的模具中。
所以我的问题是:
是其中一种反pattern,应该避免或缺点只是缺乏纪律,而与遵循的模式无关。
该模式称为模板方法模式。
,但随着时间的流逝,我感觉到这种模式,越来越多 基类中的函数具有虚拟化或更多虚拟功能 在随机位置添加并打电话给不同的派生空间 班级行为。
通常将模式应用于框架提供基类,然后由框架用户提供实际功能。在这种情况下,基类相当稳定,而用户数量和实现的可变性很大。在这种情况下,模式做得很好。
您的情况似乎有所不同,因为我知道您都可以控制基础类别和实现。如果这是真的,那么模板方法模式也不是您真正需要的。
是其中之一,是一种反模式,应该避免或缺点 只是缺乏纪律,与遵循的模式无关。
说实话,我不完全理解您的替代方法。但是,我看不到任何根本破裂的东西。但是,请考虑,如果基本和派生都不在您的控制之下,那么您的方法与模板方法方法大不相同。
任何模式都可以被滥用和过度使用。此外,没有其他模式。模式的主要好处不过是它们是模式。他们可以得到认可。您的第一个片段已被几个用户识别为模板方法模式,而第二个用户确实没有犯罪,只是另一个类层次结构。
tl; dr 模式不是圣杯。仅仅因为可能被滥用的模式并不意味着模式被打破了。如果您认为变体或完全不同的东西对您有利,请继续。
- C++多态性:如何测试一个类是否派生自另一个基类
- 派生类不能用另一个基类的成员重载基类中的私有成员
- 如果我们有一个基*类,如何访问派生模板类的成员函数
- 使从一个基类派生的类能够使用继承的受保护成员
- 如果未实现虚函数,则大多数派生类无法编译,但如果一个基类未实现虚函数,则可以编译
- 为什么将好奇模板模式的基类直接转换为另一个基类是错误的?
- C :从一个基础到另一个基类模板的动态铸造
- 从抽象基类访问另一个基类成员
- 为什么我的一个基类构造函数被删除了?(C++11).
- 创建一个基类,该基类为派生类实现单一实例
- c++抽象类在另一个基类中的实现
- 使用一个基类进行多重继承
- 如何重写另一个基类中的函数
- 虚拟继承:当只有一个基类具有"虚拟"关键字时,为什么它有效?有没有更好的方法?
- 从一个基类的指针对另一个基类的多重继承和泛型访问
- 如果一个基类有2个派生类,并且这些类每个都有一个派生类.那么我可以为大多数派生类扩展一个基方法*一次*吗
- 是否有可能有一个基类方法来调用它的所有派生类的相同(但被重写的方法)?
- 在C++中,如果没有dynamic_cast,我怎么能将一个子类实例从一个基类指针转换到另一个基类
- 对所有异常使用一个基类的缺点是什么?
- 如何在多重继承下从一个基类继承所有类型