【问题标题】:Workarounds for the forward-declared class enumeration problem?前向声明的类枚举问题的解决方法?
【发布时间】:2009-12-07 18:10:43
【问题描述】:

我正在维护一个大型代码库,并使用前向声明和 pImpl 习惯用法的组合来缩短编译时间并减少依赖项(而且效果非常好,)

我遇到的问题是包含公共枚举的类。这些枚举不能向前声明,所以我别无选择,只能包含类头。例如:

// Foo.h

class Foo
{
public:
  enum Type
  {
    TYPE_A,
    TYPE_B,
  };
  ...
};

// Bar.h

#include "Foo.h" // For Foo::Type

class Bar
{
public:
  void someFunction(Foo::Type type);
  ...
};

所以,我正在寻找避免这种情况的方法,只能想到以下几点:

将类枚举移动到单独的“类型”命名空间

// FooTypes.h

namespace FooTypes
{
  enum Type
  {
    TYPE_A,
    TYPE_B,
  };
}

// Bar.h

#include "FooTypes.h"

class Bar
{
public:
  void someFunction(FooTypes::Type type);
  ...
};

使用 int 代替枚举

// Bar.h

class Bar
{
public:
  void someFunction(int type);
  ...
};

我错过了什么?其他人如何绕过这个限制(无法转发声明枚举。)

【问题讨论】:

    标签: c++ enums pimpl-idiom


    【解决方案1】:

    将枚举放入包含 PIMPL 的类中。

    【讨论】:

    • 但是 Foo::Type 需要被许多其他类使用,而不仅仅是 Bar。我应该说清楚。
    • PIMPL 指向特定类的实现。如果在不止一个类中使用了实现,那么我认为你有一个设计问题。
    • 困惑。我有一个类,Foo,包含一个公共枚举。我想知道转发声明此枚举的方法,因此当另一个类需要将枚举用作方法参数时,我不需要#include Foo.h。我们似乎在这里有不同的目的——我显然没有很好地表达我的问题! :)
    • 抱歉,我以为您是在询问有关将枚举与 pimpls 结合使用的问题。
    【解决方案2】:

    将枚举放入自己的类型中:

    struct FooEnum
    {
      enum Type
      {
        TYPE_A,
        TYPE_B,
      };
    };
    

    那么FooBar都可以访问FooEnum::TypeBar.h不需要包含Foo.h

    【讨论】:

    • 这类似于我的“将枚举放入命名空间”的想法。将它添加到结构中是否会给我带来任何其他好处?
    • 同意。除了我猜你可以选择 Foo 和 Bar 从 FooEnum 继承来直接获取枚举类型之外,没有太多好处。不过我不确定我是否会推荐。
    • 真正的好处是通过模板来操作它,命名空间不能用作模板参数。例如,我们的大多数枚举都必须“固定”值:Invalid (0) 是最小值,NumberOfElements 是最大值(如果连续则有效),因此我们可以使用模板来检查值是否在范围内等...
    • 感谢 Matthieu - 我认为这是我最初的想法,但在发布后忘记了......
    【解决方案3】:

    我认为从一开始就枚举是一个坏主意,但一般来说,对于常量/C++ 中的常量之类的许多东西都不是常量,而且所有这些都有问题。我喜欢把它放到一个结构中,然后让使用它的类从结构继承。

    我还认为 pimpl 成语很糟糕。实际上,我确信这是一种糟糕的做事方式。这是可行的,但很尴尬而且有点愚蠢。这也很容易避免,唯一的原因是人们使用了其他糟糕的设计选择。

    通常有人只是将 OOP 的内容添加到他们设计为具体的类中。然后你会得到混合继承的情况以及它导致的大量问题,例如编译时间超慢。相反,请考虑纯虚拟基类,然后将库写入其中以避免模板并避免前向声明问题。并非适用于所有情况,但绝对适用于为大量类生成代码的情况。

    【讨论】:

      猜你喜欢
      • 2023-03-27
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-22
      • 2013-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多