首页 > 解决方案 > 有没有办法在从抽象类派生的类中使用“姐妹”函数实现?

问题描述

我有一个设计问题。如果可能的话,我想在从抽象类派生时使用“姐妹”类的函数实现。

问题

我有一些“历史”代码使用继承向基类添加行为。

旧代码

///////////////// Historic code ////////////////:

class IBase
{
    int value;
    virtual int method(){
        return value;
    };
}

class DerivedHist : IBase {
    void otherMethod(){
        return;
    }
}

新代码

经过一些修改,我最终将 IBase 专门用于 2 个派生类(Derived1 和 Derived2),并将 IBase 类更改为抽象类。问题是我想将 DerivedHist 类行为添加到两个类中,但我不知道如何以一种好的方式做到这一点。

///////////////////// New code //////////////////////////:

//this time IBase is an abstract class
class IBase
{
    int value;
    virtual int method() = 0;
}

class DerivedHist : IBase {
    void otherMethod(){
        return;
    }

    //I'd like to use Derived1's or Derived2's implementation
    virtual int method(){
        //???
    }
}

class Derived1 : IBase {
    virtual int method(){
        return 2*value;
    }
}

class Derived2 : IBase {
    virtual int method(){
        return 3*value;
    }
}

我不知道如何将 DerivedHist 类放回原处......

解决方案

我想出了一些想法:

  1. 编写 2 个等效于 DerivedHist 的类,它们继承自 Derived1(例如 Derived1Hist)和 Derived2(例如 Derived2Hist),但这意味着有两个具有几乎相同代码的类。

                                    IBase
                                    /   \
                            Derived1    Derived2
                            /               \
                        Derived1Hist        Derived2Hist
    
  2. 在 DerivedHist 构造函数中使用类似的东西:

    DerivedHist(IBase* other) : IBase(*other){
        ...
    }
    

    并使用动态转换调用它:

    Derived1 derived1(...);
    DerivedHist derivedHist(dynamic_cast<IBase*>(derived1));
    

    这不会使用 method() 的正确实现吗?正如我们可以调用 dynamic_cast(new Derived1(...))->method() 我想象在复制构造函数中传递这样的东西可以工作。我找不到用这样的东西编译代码的方法......

  3. 将 Derived[1,2] 对象之一作为成员

    class DerivedHist : IBase {
        IBase* methodHolder;
    
        DerivedHist(IBase* other) : methodHolder(other){
            ...
        }
    
        void otherMethod(){
            return;
        }
    
        virtual int method(){
            //here I'd have to copy the relevant data members to the other object
            methodHolder->value = value;
            //and then call the other method
            return methodHolder->method();
        }
    }
    

    这看起来像是 3 的最佳解决方案。

    但在这里我看到的问题是我没有从 DerivedHist 及其 methodHolder 成员同步数据。

    我可以跟踪每个更改并将其应用于 methodHolder 但这似乎不是完美的解决方案。

概括

总而言之,我的两个主要问题如下:

  1. 有没有办法从另一个派生类调用 method() 的实现?
  2. 否则,我应该使用什么样的模式来解决这个问题?

标签: c++oopinheritancedesign-patterns

解决方案


推荐阅读