一系列子类的重写方法

Override method for a family of subclasses

本文关键字:方法 重写 子类 一系列      更新时间:2023-10-16

给定遗留代码,系统具有以下类层次结构:

          Base
          ^
          |
----------+---------------
^      ^     ^     ^     ^ 
|      |     |     |     |
A1     B1    C1    D1    E1
^      ^     ^     ^     ^ 
|      |     |     |     |
A2     B2    C2    D2    E2
.......
^      ^     ^     ^     ^ 
|      |     |     |     |
An     Bn    Cn    Dn    En

层次结构表示某些特定域中的邮件。

基类

当然是所有消息的类。 答1..E1 是属于域版本 1 A2 的邮件。E2 到版本 2,依此类推。 请注意,A 必须直接从 An-1 继承,因为 A 会覆盖 An-1 的特定方法。

有一些功能是所有消息通用的,因此它被定义为 Base::P erformFeature。该功能的某些部分仅特定于版本 n,因此存在虚拟函数 Base::SpecificPartOfFeature,由 Base::P erformFunctional 调用。

所以我的问题是如何覆盖所有 An..恩。

看到了 2 种可能的解决方案,我不太喜欢:

  1. 在每个 An. 中实现 Base::SpecificPartOfFeature。恩。

    这个解决方案的问题在于每个类的实现应该完全相同,所以我只是重复代码。

    另一个问题是,如果引入了一个新的类Fn,开发人员可能会忘记实现SpecificPartOfFeature

  2. 引入从 Base 派生的 BaseN 类,而每个 An..En 派生自 BaseN 太:

    class BaseN : public Base {
       //...
       SpecificPartOfFunctionality() { ...}
    };
    class An: public An-1, public BaseN { .. }
    

    此解决方案的问题在于它引入了钻石问题。

    另一个问题是,如果其他版本m也需要覆盖Base::SpecificPartOfFeature,会发生什么。在解决方案之后,我们将引入 BaseM,它将覆盖 Base::SpecificPartOfFeature。因此,哪个 SpecificPartOfFunctional 将被调用为 BaseNBaseN 的 An-。这完全是一团糟。

有什么建议吗?

struct Base {
  virtual void PerformFunctionality() {
    stuff();
    SpecificPartOfFunctionality();
    more_stuff();
  }
private:
  virtual void SpecificPartOfFunctionality() {}
};
template<class Prev>
struct Version3 : Prev {
protected:  // Not private if v4's override might need to call this.
  virtual void SpecificPartOfFunctionality() {
    v3_specific_stuff();
  }
};
struct A1 : Base {};
struct A2 : A1 {};
struct A3 : Version3<A2> {};
struct B1 : Base {};
struct B2 : B1 {};
struct B3 : Version3<B2> {};

唯一的缺点是您无法轻松地转发当前C++中的构造函数,并且可能总是使用A2和B2的默认构造函数,只是为了简单起见。

但是,在 C++0x 中,您可以转发构造函数:

template<class Prev>
struct Version3 : Prev {
  using Prev::Prev;
  //...
};
struct C2 : C1 {
  C2(int);  // No default constructor.
};
struct C3 : Version3<C2> {
  C3() : Version3<C2>(42) {}
};

请注意,A 必须直接从 An-1 继承,因为 A 会覆盖 An-1 的特定方法。

你误解了什么。 AN不需要直接从An-1继承。 例如,这工作得很好:

struct Example {
  virtual void f();
};
template<class B>
struct Intermediate : B {};
struct Concrete : Intermediate<Example> {
  virtual void f();  // Overrides Example::f.
};

请记住,如果这不起作用,那么您的 An 首先无法从您的基类中覆盖 SpecificPartOfFeature! 在您的任何示例中,an 都不会直接从 Base 继承。

在全局范围内定义一个实现该功能的友元函数,并且SpecificPartsOfFunctionality只调用它。 例如

void FunctionalityN(Base* b)
{
    b->DoThings();
    ...
}
class An : public Base
{
    friend void FunctionalityN();
    virtual void SpecificPartOfFunctionality() { FunctionalityN(this); }
    ....
};

严格来说,FunctionN甚至不必成为朋友,尽管它会让事情变得更容易。 这使得扩展到 Fn、Gn 等变得简单,随后用 NewFunctionalityN 替换FunctionalityN也非常容易。