扩展C+中的枚举+;? 在C++中有没有一种方法可以扩展/继承“枚举”?< /p>
即:扩展C+中的枚举+;? 在C++中有没有一种方法可以扩展/继承“枚举”?< /p>,c++,enums,C++,Enums,即: 或者至少定义它们之间的转换?以下代码运行良好 enum Enum {A,B,C}; enum EnumEx {D=C+1,E,F}; 如果您能够创建枚举的子类,那么它必须以另一种方式工作 子类中的实例集是超类中实例的子集。考虑一下标准的“形状”示例。Shape类表示所有形状的集合。Circle类及其子类表示圆形形状的子集 因此,为了保持一致,枚举的子类必须包含它继承自的枚举中元素的子集 (也不,C++不支持这个)。 < P>不,没有。 《C++》中的代码> > EnUM 真的是很糟糕的事
或者至少定义它们之间的转换?以下代码运行良好
enum Enum {A,B,C};
enum EnumEx {D=C+1,E,F};
如果您能够创建枚举的子类,那么它必须以另一种方式工作 子类中的实例集是超类中实例的子集。考虑一下标准的“形状”示例。Shape类表示所有形状的集合。Circle类及其子类表示圆形形状的子集 因此,为了保持一致,枚举的子类必须包含它继承自的枚举中元素的子集
(也不,C++不支持这个)。
< P>不,没有。 《C++》中的代码> > EnUM <代码>真的是很糟糕的事情,当然这是不幸的。 甚至C++0x中引入的类enum
也没有解决这个扩展性问题(尽管它们至少为类型安全做了一些事情)
enum
的唯一优点是它们不存在:它们提供了某种类型安全性,同时不会造成任何运行时开销,因为编译器会直接替换它们
如果你想要这样一头野兽,你必须自己动手:
- 创建一个包含int(基本上)的类
- 为每个感兴趣的值创建命名构造函数
不过这是一个解决办法,我从未找到一种令人满意的方法来处理枚举…我用这种方法解决了:
typedef enum
{
#include "NetProtocols.def"
} eNetProtocols, eNP;
当然,如果在NetProtocols.def文件中添加新的网络协议,则必须重新编译,但至少它是可扩展的
“NetProtocols.def”将仅包含字段名:
HTTP,
HTTPS,
FTP
查看创建扩展枚举的方法。只是一个想法:
您可以尝试为每个常量创建一个空类(可能将它们都放在同一个文件中以减少混乱),为每个类创建一个实例,并使用指向这些实例的指针作为“常量”。这样,编译器将理解继承,并在使用函数调用时执行任何必要的ChildPointer到ParentPointer的转换,并且编译器仍会进行类型安全检查,以确保没有人向函数传递无效的int值(如果使用最后一个value方法“扩展”枚举,则必须使用该方法)
不过,我还没有充分考虑到这一点,所以欢迎对这种方法发表任何评论
我会在我有一段时间之后,发布一个我的意思的例子。
< P>一个简单但有用的C++间隙的解决方法可以如下:#define ENUM_BASE_VALS A,B,C
enum Enum {ENUM_BASE_VALS};
enum EnumEx {ENUM_BASE_VALS, D,E,F};
在我设计的一些小型硬件设备上运行的项目中,我遇到了这个问题。有一个包含许多服务的公共项目。其中一些服务使用枚举作为参数,以获得额外的类型检查和安全性。我需要能够在使用这些服务的项目中扩展这些枚举
正如其他人提到的,C++不允许你扩展枚举。但是,您可以使用具有枚举类所有优点的命名空间和模板来模拟枚举
枚举类具有以下优点:template <typename TYPE>
class EnumClass {
private:
TYPE value_;
public:
explicit constexpr EnumClass(TYPE value) :
value_(value){
}
constexpr EnumClass() = default;
~EnumClass() = default;
constexpr explicit EnumClass(const EnumClass &) = default;
constexpr EnumClass &operator=(const EnumClass &) = default;
constexpr operator TYPE() const {return value_;}
constexpr TYPE value() const {return value_;}
};
模板
类枚举类{
私人:
类型值;
公众:
显式constexpr枚举类(类型值):
价值(价值){
}
constexpr EnumClass()=默认值;
~EnumClass()=默认值;
constexpr explicit EnumClass(const EnumClass&)=默认值;
constexpr EnumClass&运算符=(const EnumClass&)=默认值;
constexpr运算符类型()const{返回值}
constexpr TYPE value()常量{返回值}
};
然后,对于我们要扩展和模拟的每个枚举类,我们创建一个名称空间和一个类型,如下所示:
namespace EnumName {
class Type :public Enum<uint8_t> {
public:
explicit constexpr Type(uint8_t value): Enum<uint8_t>(value){}
constexpr Enum() = default;
}
constexpr auto Value1 = Type(1);
constexpr auto Value2 = Type(2);
constexpr auto Value3 = Type(3);
}
#include <iostream>
void fn(EnumName::Type val){
if( val != EnumName::Value1 ){
std::cout << val;
}
}
int main(){
for( auto e :EnumName::Set){
switch(e){
case EnumName::Value1:
std::cout << "a";
break;
case EnumName::Value4:
std::cout << "b";
break;
default:
fn(e);
}
}
}
名称空间枚举名{
类类型:公共枚举{
公众:
显式constexpr类型(uint8_t值):枚举(值){}
constexpr Enum()=默认值;
}
constexpr auto Value1=类型(1);
constexpr auto Value2=类型(2);
constexpr auto Value3=类型(3);
}
然后,在代码的后面部分,如果已包含原始枚举名,则可以执行以下操作:
namespace EnumName {
constexpr auto Value4 = Type(4U);
constexpr auto Value5 = Type(5U);
constexpr auto Value6 = Type(6U);
constexpr std::array<Type, 6U> Set = {Value1, Value2, Value3, Value4, Value5, Value6};
}
名称空间枚举名{
constexpr自动值4=类型(4U);
constexpr自动值5=类型(5U);
constexpr自动值6=类型(6U);
constexpr std::数组集={Value1,Value2,Value3,Value4,Value5,Value6};
}
现在可以像这样使用枚举:
namespace EnumName {
class Type :public Enum<uint8_t> {
public:
explicit constexpr Type(uint8_t value): Enum<uint8_t>(value){}
constexpr Enum() = default;
}
constexpr auto Value1 = Type(1);
constexpr auto Value2 = Type(2);
constexpr auto Value3 = Type(3);
}
#include <iostream>
void fn(EnumName::Type val){
if( val != EnumName::Value1 ){
std::cout << val;
}
}
int main(){
for( auto e :EnumName::Set){
switch(e){
case EnumName::Value1:
std::cout << "a";
break;
case EnumName::Value4:
std::cout << "b";
break;
default:
fn(e);
}
}
}
#包括
void fn(EnumName::Type val){
如果(val!=EnumName::Value1){
std::cout实际上,您可以以一种循环的方式扩展枚举
C++标准定义有效枚举值为所有类型的有效值,因此下面的是有效的C++(11 +)。它不是未定义的行为,但它非常讨厌——你已经被警告过了。
#include <cstdint>
enum Test1:unit8_t {
Value1 =0,
Value2 =1
};
constexpr auto Value3 = static_cast<Test1>(3);
constexpr auto Value4 = static_cast<Test1>(4);
constexpr auto Value5 = static_cast<Test1>(5);
Test1 fn(Test1 val){
switch(val){
case Value1:
case Value2:
case Value3:
case Value4:
return Value1;
case Value5:
return Value5;
}
}
int main(){
return static_cast<uint8_t>(fn(Value5));
}
#包括
枚举测试1:unit8\t{
值1=0,
值2=1
};
constexpr auto Value3=static_cast(3);
constexpr auto Value4=static_cast(4);
constexpr auto Value5=static_cast(5);
测试1 fn(测试1 val){