我是c++的新手,我想知道是否有人可以帮助我理解为什么
enum difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDiffiuclty = EASY
和
enum shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;
用绿色下划线?它说它更喜欢enum类,但当我把它改成enum类,然后
enum class difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDiffiuclty = EASY;
enum class shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;
EASY变成红色下划线myShipCost用绿色下划线,BOMBER_COST用红色下划线,CRUISER_COST用红色下划线
const int ALIEN_POINTS = 150;
int aliensKilled = 10;
int score = aliensKilled * ALIEN_POINTS;
cout << "score: " << score << endl;
enum difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDifficulty = EASY;
enum shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = BOMBER_COST;
cout << "nTo upgrade my ship to a cruiser will cost "
<< (CRUISER_COST - myShipCost) << " Resource Points.n";
system("pause");
return 0;
enum class difficulty { NOVICE, EASY, NORMAL, HARD, UNBEATABLE };
difficulty myDiffiuclty = difficulty::EASY;
enum class shipCost { FIGHTER_COST = 25, BOMBER_COST, CRUISER_COST = 50 };
shipCost myShipCost = shipCost::BOMBER_COST;
与enum class
,隐式转换到/从整数,和你必须限定其中的常量的作用域。
这被认为是一种改进。显式地将其转换回整数仍然有效,但这不是偶然发生的。
std::cout << "nTo upgrade my ship to a cruiser will cost "
<< (static_cast<int>(shipCost::CRUISER_COST) - static_cast<int>(myShipCost)) <<
" Resource Points.n";
system("pause");
return 0;
一旦你使用enum class
,你应该重命名它们:
enum class difficulty { novice, easy, normal, hard, unbeatable };
difficulty myDiffiuclty = difficulty::easy;
enum class shipCost { fighter =25, bomber=30, cruiser = 50 };
shipCost myShipCost = shipCost::bomber;
作为名称的ship
部分现在在enum
中,不需要在常量中重复。同样,因为名称是有作用域的,所以您不必对它们进行SHOUT
。
namespace ship {
namespace cost {
constexpr int fighter = 25;
constexpr int bomber = 30;
constexpr int cruiser = 50;
}
}
现在我们将ship::cost::fighter
作为编译时计算的int
,而不是enum class
。
现在您已经了解了上述答案的区别,我想指出"new"的几个地方。做事的方式坏了,你能做些什么。
考虑一下我遇到的这个(缩写的)实际例子,将我用C编写的一些音频软件移植到现代c++ (c++ 17):
typedef enum sample_type_e {
sample_type_uint16,
sample_type_double
}sample_type_t;
现在,首先要知道的是这里不再需要typedef;你可以在其他地方读到更多。继续…
此代码在Visual Studio 2019中编译,将导致您描述的错误。
现在,解决这个问题的一个方法将看起来像是移动到新的语法——但是看看会发生什么:
enum class SampleType {
uint16,
double
}
哦。
这行不通——double是保留字。现在,您可以恼怒地这样做:
enum class SampleType {
uint16,
type_double
}
…但这不是很一致,当你看到这个时:
enum class SampleType {
type_uint16,
type_double
}
…可以说,您已经达到了与这个新特性所声称的至少一个好处完全相反的效果:尽可能简洁,而不丢失上下文。
在我的假想但实际上是真实世界的例子中,麻烦的是你不能限定保留字的作用域:它们总是保留。(切线点:在某些语言中,这是不正确的…)
这就叫做"不走运"。它发生的频率比语言设计师愿意承认的要高得多,而且当你没有他们中的一个和你在一起的时候,它总是会出现。
所以,如果类似的事情碰巧出现在你面前,而你只是真的不喜欢尝试使用"class enum"最后看起来像,你会怎么做?
嗯,事实证明,您可以通过使用另一个语言特性来解决整个原始问题,该特性被认为是尽可能使用的良好实践:名称空间。如果我只对原始声明命名空间(减去粗糙的typedef),我得到:
namespace audiostuff {
enum sample_type_e {
sample_type_uint16,
sample_type_double
};
};
…只要使用这些东西的代码在相同的命名空间中,或者有
using namespace audiostuff;
放在最上面,或者,交替使用,像这样:
audiostuff::sample_type_e my_sample_type_var;
…然后,你瞧,Visual Studio停止了抱怨——其他编译器也应该停止抱怨。
毕竟,这个抱怨是在提醒您应该避免弄乱全局命名空间——尤其是在意外情况下。"类enum"是一种方法,但使用显式命名空间也是一种方法。