Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 可选功能的设计模式?_C++_Design Patterns_Inheritance_Derived Class - Fatal编程技术网

C++ 可选功能的设计模式?

C++ 可选功能的设计模式?,c++,design-patterns,inheritance,derived-class,C++,Design Patterns,Inheritance,Derived Class,我有一个派生子类继承自的基本类,它承载的基本函数在所有派生类中应该是相同的: class Basic { public: Run() { int input = something->getsomething(); switch(input) { /* Basic functionality */ case 1: doA();

我有一个派生子类继承自的基本类,它承载的基本函数在所有派生类中应该是相同的:

class Basic {
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            case 1:
                doA();
                break;
            case 2:
                doB();
                break;
            case 5:
                Foo();
                break;
        }
    }
};
现在,基于派生类,我想向开关“添加”更多case语句。我的选择是什么?我可以声明虚拟函数,并且只能在将要使用它们的派生类中定义它们:

class Basic {
protected:
    virtual void DoSomethingElse();
public:
    Run() {
        int input = something->getsomething();
        switch(input)
        {
            /* Basic functionality */
            ...

            case 6:
                DoSomethingElse();
        }
    }
};


class Derived : public Basic {
protected:
    void DoSomethingElse() { ... }
}
但这意味着在任何派生类中更改函数时,我必须编辑基类以反映这些更改


是否有专门针对此类问题的设计模式?我买了很多关于设计模式的书,但我在“按需”的基础上研究它们,所以我不知道是否有我正在寻找的这种模式。

处理这种情况的正常方法是使用工厂。概述:

  • 创建提供功能的相关类的层次结构
  • 创建一个接受输入的工厂类,并根据输入创建正确类型的类的实例
现在,有关附加积分:

  • 创建一个在工厂中注册类的方案-您需要指定输入和类的类型来处理它

现在,当需要新输入时,您只需派生一个新类并向工厂注册它。对switch语句的需求消失了。

我认为您需要的模式是责任链或者策略与动态呼叫表相结合

但这意味着当改变时 任何派生类中的函数,I 将必须编辑我的基类以 反映这些变化

为什么这是真的


我不在乎你的评论——那么如果你选择这种方法,你就会有这些问题。其他人发布了建议其他解决方案的答案-我会查看这些答案,看看它们是否对您有帮助。

您可能会发现阅读并以这种方式重新思考您的解决方案很有用

您还可以将“doRun”声明为受保护的方法,并在基本默认情况下调用它

default:
   doRun(input);
并在派生类中定义doRun


这就是所谓的

如果选择器值只是小整数,我将用查找表替换case语句。(本例中的每个操作都需要作为函数进行编码,以便将函数指针放入表中)。然后继承的类就可以将条目添加到表中。(我猜表必须是实例属性,不能是静态的)

Colin

是一种简单的解决方案:

class Basic {
  public:
    void Run() {
      const int input = ...
      if (!(BaseProcess(input) || Process(input))) ...
    }

    vitual bool Process(int input) { return false; }

    bool BaseProcess(int input) {
      switch(input) {
    ...
        default: return false;
      }
      return true;
    }
...
…然后在子类“Process()中实现其他案例。
如果您需要支持两个以上的级别(即子类添加更多的案例),那么您将需要一个动态调度表。

也许我的措辞不好。当我更改一个函数的内容时,我不必这样做,但是当我删除一个函数或更改其名称时,我必须返回基本类来反映这些更改。另外,我不想以一个拥有大量虚拟函数的“基本”类结束;在任何派生自它的类中,每个函数对应一个。只有当基本类需要虚拟函数时,才是这样。。。任何一段代码都会在基本类对象上调用这样的函数,还是它们只是在子类中供私人使用?如果每个对象的类类型都是已知的(也就是说,您不需要多态性,这似乎是事实),那么您不需要在基类中声明虚拟函数,但是我对C++比较陌生,还没有深入研究它们,知道如何使用它们,并且使用不同的参数。我想现在我将使用模板方法模式。我一定会阅读并考虑这里列出的其他模式,但现在这可以被标记为接受:)我将尝试澄清我的推理多一点:我不需要基于输入导出:派生类不会生活在堆栈上。我只想分离不同类型的逻辑,但仍然为所有派生类保留一些“基本”逻辑。