【问题标题】:Giant switch statement for constructors构造函数的巨大 switch 语句
【发布时间】:2023-03-03 00:16:01
【问题描述】:

我有一个容器,其中包含一堆指向基类的指针,以及一个接受一些输入并返回一个类的函数,该类是基类的子类。它返回哪个子类取决于输入。

现在,我有一个像这样的巨大 switch 语句:

class Base { ... }

class A : public Base { ... }
class B : public Base { ... }
...
class Z : public Base { ... }

Base* depends(int input) {
    switch (input) {
    case 1:
        return new A(...);
    case 2:
        return new B(...);
    ...
    case 26:
        return new Z(...);
    default:
        ...
    }
}

我想知道是否有更好的设计方法。我不知道很多“设计模式”(我认为这就是他们所说的)所以我不知道是否有(明显的)更好的设计方法。

【问题讨论】:

  • 最好有一个字典将你的键映射到类或类名(或者如果你的键是整数,则只是一个数组)。但这可能吗?见类似问题:stackoverflow.com/questions/582331/…
  • @Ray 感谢您的链接,该问题与我的非常相似,并且几乎可以回答问题。

标签: c++ inheritance switch-statement class-hierarchy construction


【解决方案1】:

整数参数“input”来自某个地方。您也许可以让创建该 int 的代码改为创建实际对象。如果您从磁盘或类似的东西读取 int,那将不起作用。

您可能会考虑设置不同的子类向创建它们的对象注册自己的情况。在这种情况下,工厂对象不需要在编译时知道子类。您可以在启动时使用全局变量来完成此操作,全局变量的构造函数为每个子类进行注册。您的 switch 语句更简单、更快,但这确实意味着您必须在更改子类时使 switch 保持最新。这是一种权衡,我认为您的解决方案不一定不如更精细的解决方案。

【讨论】:

  • 不幸的是,这正是这个程序所做的——从文件中读取数据。这个程序需要它可以得到的每一点效率,所以我认为坚持使用switch 将是一个好方法。谢谢。
  • @Seth Carnegie 您可能想做的一件事是让子类定义一个静态常量字段,如 classId。那么创建对象的代码和将id写入磁盘的代码都可以引用同一个字段。
  • 是的,它就是这么做的。我宁愿那样做那个 RTTI。
【解决方案2】:

您要查找的是 Factory Method pattern

这里重要的是消除基类对派生类实现的任何知识的需要。对于基类来说,了解派生类是一个糟糕的设计。

工厂方法模式解决了上述问题,因为创建发生在基类之外。

【讨论】:

    【解决方案3】:

    另一种方法是创建一个数组,您将在其中放置指向将调用相应构造函数的函数的指针。在您的depends() 中,您只会通过给定的输入调用您需要的函数。但无论如何,这种方法需要 26 个函数

    【讨论】:

      【解决方案4】:

      这有点难以弄清楚你的意图,但如果你想根据一些输入参数创建一堆不同的子类,你可能需要考虑抽象工厂模式。

      【讨论】:

        猜你喜欢
        • 2012-10-07
        • 1970-01-01
        • 2015-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多