仅在某些子类中重写相同的方法,如何避免重复?

时间:2009-06-20 18:56:24

标签: c++ oop polymorphism

我正在使用基类,目前有5个子类。其中一些功能与3个孩子相似,但不是全部。我不能引入新的层次结构,因为一些方法在子1,2,3和2,3,4中重复。

如何最好地避免覆盖所有3个孩子中的方法并重复代码。

8 个答案:

答案 0 :(得分:3)

如果您不想使用多重继承,也可以使用合成

将公共代码放入一个特殊类中,并将类的实例添加到需要代码的子类中。然后,您可以导航到该功能或将调用包装到访问方法(内联)。

答案 1 :(得分:1)

创建一个混合类,让具有共同方法的子代也从中继承。例如:

class Base {
  public:
    virtual commonFunction() { /* default implementation */ };
}; 

class Mixin {
  public:
     virtual notSoCommonFunction() { /* default implementation */ };
};

class D1 : public Base {
  public:
     virtual commonFunction() { /* override implementation */ };
};

class D2 : public Base, public Mixin {
  public:
     virtual commonFunction() { /* override implementation */ };
     virtual notSoCommonFunction() { /* override implementation */ };
};

class D3 : public Base, public Mixin {
  public:
     virtual commonFunction() { /* override implementation */ };
     virtual notSoCommonFunction() { /* override implementation */ };
};

因此所有类D1,D2,D3都实现(并且可选地覆盖)commonFunction,但只有D2和D3实现(并且可选地覆盖notSoCommonFunction)。

答案 2 :(得分:1)

您可以为每个函数的不同实现添加一个带有protected方法的新中间类。然后在子类中重写原始基类中的方法,并从这个新的中间类调用相应的protected方法。

class Base {
    public void foo() { /* ... */ }
    public void bar() { /* ... */ }
}

class Middle extends Base {
    protected void foo1() { /* ... */ }
    protected void foo2() { /* ... */ }
    protected void bar1() { /* ... */ }
    protected void bar2() { /* ... */ }
}

class Child1 extends Middle {
    // Use default foo()
    public void bar() { bar1(); }
}

class Child2 extends Middle {
    public void foo() { foo1(); }
    public void bar() { bar2(); }
}

class Child3 extends Middle {
    public void foo() { foo2(); }
    // Use default bar()
}

答案 3 :(得分:1)

或者你可以探索Strategy pattern。有时,HAS-A关系是比IS-A更好的选择。当然,我不知道你的问题是否允许引入模式

答案 4 :(得分:0)

上面的大多数答案都谈到了使用新类,但我使用的方法调用了该类的许多其他方法,并且还使用了一些类实例变量。如果我使用mixin或撰写新类,我将无法实现该方法。

答案 5 :(得分:0)

如果您需要访问该类的其他成员,可以使用static_cast this指向相应类型的模板化mixins:

template<class T>
class M1Mixin {
public:
   int m1() {
     return static_cast<T*>(this)->some_value;
   }
};


class Base {
public:
  int some_value;
  ...
};

class A : public Base, M1Mixin<A> {
  ...
};

它不漂亮,但它有效。

答案 6 :(得分:0)

代码审查可以在您得到满意答案之前等待,对吧?凉。 : - )

答案 7 :(得分:0)

可能有效的另一种解决方案如下:

假设基类名为MyBaseClass,子类是ChildClass1到ChildClass5,并且要复制的函数如下所示:

public int foo(Object args)
{...}

现在您可以使用静态方法创建一个单独的类(称为“HelperFunctions”或其他类):

public static int fooHelper(BaseClass theClass, Object args)
{insert duplicated code here}

然后在你想要调用辅助函数的类中使用foo函数。

这有一些优点:

  1. 您不是在创建新对象或更改类型层次结构。由于辅助函数是静态的,因此无需任何新对象即可调用它。
  2. 你仍然可以调用类的方法,因为你传入了BaseClass类型的对象,所以你可以像在类中一样调用它上面的方法。
  3.   

    上面的大多数答案都谈到了使用新类,但我使用的方法调用了该类的许多其他方法,并且还使用了一些类实例变量。如果我使用mixin或撰写新类,我将无法实现该方法。

    我不确定我明白问题所在。至少在我的解决方案中,您传入了对象,因此您可以调用任何方法并访问所需对象上的实例变量。您要访问的实例变量或方法是否为私有问题,以至于您无法在类外访问它们?在这种情况下,您可以通过将辅助函数声明为友元函数来轻松解决它(只需谷歌“c ++ friend函数”以获取有关如何使用它们的教程)