2

如果你想用一个类包装一些枚举类型,例如,围绕它构建一些函数,你最终可能会遇到以下情况:

主.cpp:

#include "WrappedEnumConstants.h"

int main(int argc, char * argv[])
{
   WrappedZero.print();
   WrappedOne.print();
}

WrappedEnumConstants.h

#ifndef WRAPEDENUMCONSTANTS_H
#define WRAPEDENUMCONSTANTS_H

#include "WrappedEnum.h"
#include "InternalEnum.h"

static const WrappedEnum WrappedZero(ZeroEnum);
static const WrappedEnum WrappedOne(OneEnum);

#endif

WrappedEnum.h

#ifndef WRAPPEDENUM_H
#define WRAPPEDENUM_H

#include <iostream>
#include "InternalEnum.h"

class WrappedEnum
{
public:
   WrappedEnum(InternalEnum a);
   void print() const;
private:
   InternalEnum a;
};
#endif

WrappedEnum.cpp

#include <iostream>
#include "WrappedEnum.h"

WrappedEnum::WrappedEnum(InternalEnum a) :
   a(a)
{}

void WrappedEnum::print() const {
   std::cout << "WrappedEnum: " << a << std::endl;
}

内部枚举.h

#ifndef INTERNALENUM_H
#define INTERNALENUM_H
   enum InternalEnum { ZeroEnum, OneEnum};
#endif

我得到的输出与预期的一样:

WrappedEnum: 0
WrappedEnum: 1

我想知道静态常量 WrappedZero 和 WrappedOne 的初始化是否安全。ZeroEnum 和 OneEnum 的常量是否保证在 WrappedZero 和 WrappedOne 之前被初始化,还是我只是幸运?特别是,我想知道如果您在一个将许多东西链接在一起的大型项目中使用 WrappedEnum 可能会遇到什么陷阱。你有看到吗?

枚举常量(如 ZeroEnum 和 OneEnum)和全局“静态 const int”的初始化是否存在差异?

4

2 回答 2

1

ZeroEnum 和 OneEnum 的常量是否保证在 WrappedZero 和 WrappedOne 之前被初始化,还是我只是幸运?

它们是编译时常量,因此根本不会在运行时初始化。随时使用它们是安全的。

枚举常量(如 ZeroEnum 和 OneEnum)和全局“静态 const int”的初始化是否存在差异?

如果static const int用一个常量值初始化,它将是任何知道其值的代码中的编译时常量。否则,它将在程序启动之前的静态初始化阶段进行初始化。无论哪种情况,随时使用它也是安全的。

如果需要使用运行时值对其进行初始化,那么它将在动态初始化阶段进行初始化(如您的“包装”对象),并且您可能会遇到初始化顺序问题。

于 2013-09-13T16:42:02.390 回答
0

是,有一点不同。

实例中的枚举类型字段在编译时用于编译器未知,因此在生成代码时,它被迫实际访问实例以查找值,并且生成的代码会更大更慢。

Aconst int 可以在编译时知道(如果您使用常量对其进行初始化),因此编译器可以生成直接使用该值的代码(您也可以将其用作常量表达式,例如在数组声明或模板中)。

另请注意,将值包装在静态持续时间实例中会给谁将在其他静态持续时间实例的初始化期间使用这些包装的值带来问题,因为无法保证初始化的顺序。

我不太确定为什么您认为将包含所需物品的盒子包装在袋子中是个好主意。除了编写更多代码并让编译器和您的用户烦恼之外,您这样做有什么好处?

于 2013-09-13T16:46:24.520 回答