在编码实践方面,在什么情况下全局常量优先于枚举,反之亦然?
例如,假设我需要一种在全局范围内表达各种tile sprite的方法。我能做到......
const int TILE_RED = 0;
const int TILE_GREEN = 1;
const int TILE_BLUE = 2;
const int TILE_CENTER = 3;
const int TILE_TOP = 4;
const int TILE_TOPRIGHT = 5;
const int TILE_RIGHT = 6;
const int TILE_BOTTOMRIGHT = 7;
const int TILE_BOTTOM = 8;
const int TILE_BOTTOMLEFT = 9;
const int TILE_LEFT = 10;
const int TILE_TOPLEFT = 11;
或
enum Tile { TILE_RED, TILE_GREEN, TILE_BLUE, TILE_CENTER, TILE_TOP, TILE_TOPRIGHT
TILE_RIGHT, TILE_BOTTOMRIGHT, TILE_BOTTOM, TILE_BOTTOMLEFT, TILE_LEFT, TILE_TOPLEFT };
显然我们更喜欢常量和枚举到宏,但是当它归结为常量和枚举时呢?什么情况更喜欢什么?我读here,不断的对象会使你的程序变慢,但是我想听听别人的想法。
我特别使用了这个例子,因为它是一大堆相关对象 - 用于枚举的猫的睡衣。
答案 0 :(得分:4)
枚举的两个相关优势是它们的自我记录性质,以及它们保持名称空间更清晰的事实。基本上,枚举就像它们自己的命名空间中的语义相关常量的捆绑。通过在接口中使用枚举,可以隐式指示预期的值集。
编辑:更正! (我最近做了太多的C#,而且C / C ++还不够!)
使用C和C ++ 枚举中的标识符的范围与普通变量和常量相同,因此必须与同一范围内的任何其他标识符不同,包括其他枚举列表中的标识符。这与enum引入自己的命名空间的更现代的语言不同。 C / C ++枚举有助于保持名称空间整洁的概念因此是不正确的。感谢Michael Burr指出这一点。
枚举的主要缺点是不便于携带。明确定义了常量类型和值,枚举的清晰度较低。
答案 1 :(得分:4)
关于枚举的一个好处是它们可以在C和C ++之间移植,而const
项不能在C中用于您可能喜欢的所有位置(如数组声明)。因此,对于我想在C或C ++中工作的头文件,我倾向于使用枚举优先于const声明或宏定义。实际上我倾向于使用它们,无论标题是否仅适用于C ++(我不得不考虑一个决定)。
使枚举的类型不明确不是经常出现的问题 - 如果你根据各种不同的整数类型进行重载,你将会遇到枚举的潜在问题,在这种情况下,const项可能会更好。但是我不记得上次我对不同类型的相同数字需要不同的行为(即,5U
与5
或5L
不同)。我认为这种类型的重载只能在拼图/访谈类型的问题中看到,或者无论你是否使用枚举,它的代码都会产生bug。
所以底线是我更喜欢枚举 - 但祝你的同事停止使用宏好运。对于命名常量使用宏在C / C ++文化中根深蒂固,即使它们大大污染了命名空间,也没有足够的真正的单词问题来说服许多人甚至考虑改变习惯。
答案 2 :(得分:2)
当常量的值不重要或按照示例中的顺序时使用枚举。
如果需要为标识符分配特殊常量值,请使用常量。
答案 3 :(得分:1)
枚举的最大优点是它可以由编译器强制执行,而不是常量的情况。
答案 4 :(得分:0)
非显式枚举可能会导致某些平台兼容性问题,而且它们也不是类型安全的。全局常量是类型安全的并且通常是首选的。但是,如果你忽略了这一点,枚举通常用于相关事物和常量以获得更多不相关的东西。
使用枚举时的示例:
enum Colors {
COLOR_RED=0xFF0000,
COLOR_GREEN=0x00FF00,
COLOR_BLUE=0x0000FF
}
使用全局consts时的示例:
volatile const void *VRAM=0x00FC0000;
最后,我的建议是,如果您真的关心平台兼容性,那么请使用全局竞争。
答案 5 :(得分:0)
当没有特殊的向后兼容性原因时,我更喜欢向前兼容性。
在这种情况下,使用全局consts更加独立于编译器,但我投票支持枚举有几个原因:
1. consts可能有不同的类型。当你想要替换你的枚举类型时,只需要一个糟糕的搜索替换。它可能会导致一些意想不到的影响(考虑签名/未签名和值大小)。在枚举中强制执行单一类型
2.强类型枚举在C ++ 0x中引入。在C ++中已经有了一些实现。
冥想,恕我直言,很难用不清楚的方式写。你不能说在consts上(分布在几个文件等)。
BTW,如果你使用const,我更喜欢在类范围内使用静态consts(而不是全局)。