我想做的事情如下:
enum E;
void Foo(E e);
enum E {A, B, C};
编译器拒绝它。我在谷歌上快速浏览了一下,共识似乎是“你做不到”,但我不明白为什么。有人能解释一下吗?
澄清2:我这样做是因为我在一个类中有私有方法,它采用所说的枚举,我不希望枚举的值暴露出来-因此,例如,我不希望任何人知道E被定义为
enum E {
FUNCTIONALITY_NORMAL, FUNCTIONALITY_RESTRICTED, FUNCTIONALITY_FOR_PROJECT_X
}
项目X不是我想让我的用户知道的东西。
所以,我想要转发声明枚举,这样我就可以把私有方法放在头文件中,在cpp中内部声明枚举,并将构建的库文件和头分发给人们。
至于编译器——它是GCC。
在c++ 11中,你可以前向声明一个枚举,只要同时声明它的存储类型。语法如下所示:
enum E : short;
void foo(E e);
....
enum E : short
{
VALUE_1,
VALUE_2,
....
}
事实上,如果函数从未引用枚举的值,那么此时根本不需要完整的声明。
g++ 4.6及以后的版本(-std=c++0x或-std=c++11在最近的版本中)都支持这一点。Visual c++ 2013支持此功能;在早期版本中,它有一些我还没有弄清楚的非标准支持-我发现了一些建议,简单的向前声明是合法的,但您的哩数可能会有所不同。
如果您真的不希望枚举出现在头文件中,并确保它只被私有方法使用,那么一种解决方案是遵循PIMPL原则。
这是一种确保在头文件中隐藏类内部信息的技术,只需声明:
class A
{
public:
...
private:
void* pImpl;
};
然后在实现文件(.cpp)中声明一个类,该类将作为内部结构的表示。
class AImpl
{
public:
AImpl(A* pThis): m_pThis(pThis) {}
... all private methods here ...
private:
A* m_pThis;
};
你必须在类构造函数中动态创建实现,并在析构函数中删除它,当实现公共方法时,你必须使用:
((AImpl*)pImpl)->PrivateMethod();
使用PIMPL有优点。一个是它将类头与其实现解耦,并且在更改一个类实现时不需要重新编译其他类。另一个原因是加快了你的编译时间,因为你的头文件太简单了。
但它使用起来很痛苦,所以你应该问问自己,仅仅在头文件中将枚举声明为private是否有那么大的麻烦。