C++ 基本枚举类继承
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/644629/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Base enum class inheritance
提问by Mykola Golubyev
Is there a pattern where I can inherit enum from another enum in C++??
有没有一种模式可以让我从 C++ 中的另一个枚举继承枚举??
Something like that:
类似的东西:
enum eBase
{
one=1, two, three
};
enum eDerived: public eBase
{
four=4, five, six
};
采纳答案by Brian R. Bondy
Not possible. There is no inheritance with enums.
不可能。枚举没有继承。
You can instead use classes with named const ints.
您可以改为使用具有命名 const int 的类。
Example:
例子:
class Colors
{
public:
static const int RED = 1;
static const int GREEN = 2;
};
class RGB : public Colors
{
static const int BLUE = 10;
};
class FourColors : public Colors
{
public:
static const int ORANGE = 100;
static const int PURPLE = 101;
};
回答by Mykola Golubyev
#include <iostream>
#include <ostream>
class Enum
{
public:
enum
{
One = 1,
Two,
Last
};
};
class EnumDeriv : public Enum
{
public:
enum
{
Three = Enum::Last,
Four,
Five
};
};
int main()
{
std::cout << EnumDeriv::One << std::endl;
std::cout << EnumDeriv::Four << std::endl;
return 0;
}
回答by Kirill V. Lyadvinsky
You can't do that directly, but you could try to use solution from thisarticle.
你不能做到这一点直接,但你可以尝试使用的解决方案,从这个文章。
The main idea is to use the helper template class which holds enum values and has the type cast operator. Considering that the underlying type for enum is int
you can use this holder class seamlessly in your code instead of the enum.
主要思想是使用包含枚举值并具有类型转换运算符的辅助模板类。考虑到 enum 的基础类型是int
您可以在代码中无缝使用这个 holder 类而不是 enum。
回答by Ог?ен Шоба?и?
Unfortunately it is not possible in C++14. I hope we will have such a language feature in C++17. As you already got few workarounds for your problem I won't provide a solution.
不幸的是,在 C++14 中这是不可能的。我希望我们在 C++17 中会有这样的语言特性。由于您的问题已经很少有解决方法,因此我不会提供解决方案。
I would like to point out that the wording should be "extension" not "inheritance". The extension allows for more values (as you're jumping from 3 to 6 values in your example) whereas inheritance means putting more constraints to a given base class so the set of possibilities shrinks. Therefore, potential casting would work exactly opposite from inheritance. You can cast derived class to the base class and not vice-verse with class inheritance. But when having extensions you "should" be able to cast the base class to its extension and not vice-verse. I am saying "should" because, as I said such a language feature still doesn't exist.
我想指出,措辞应该是“扩展”而不是“继承”。扩展允许更多值(因为您在示例中从 3 个值跳到 6 个值),而继承意味着对给定基类施加更多约束,因此可能性集会缩小。因此,潜在的强制转换将与继承完全相反。您可以将派生类转换为基类,反之亦然。但是当有扩展时,你“应该”能够将基类转换为它的扩展,反之亦然。我说“应该”是因为,正如我所说,这样的语言功能仍然不存在。
回答by Dirk
How about this? Ok an instance is created for every possible value, but besides that its very flexible. Are there any downsides?
这个怎么样?好的,为每个可能的值创建了一个实例,但除此之外,它非常灵活。有什么缺点吗?
.h:
。H:
class BaseEnum
{
public:
static const BaseEnum ONE;
static const BaseEnum TWO;
bool operator==(const BaseEnum& other);
protected:
BaseEnum() : i(maxI++) {}
const int i;
static int maxI;
};
class DerivedEnum : public BaseEnum
{
public:
static const DerivedEnum THREE;
};
.cpp:
.cpp:
int BaseEnum::maxI = 0;
bool BaseEnum::operator==(const BaseEnum& other) {
return i == other.i;
}
const BaseEnum BaseEnum::ONE;
const BaseEnum BaseEnum::TWO;
const DerivedEnum DerivedEnum::THREE;
Usage:
用法:
BaseEnum e = DerivedEnum::THREE;
if (e == DerivedEnum::THREE) {
std::cerr << "equal" << std::endl;
}
回答by Dmitry Bravikov
You can use a project SuperEnumto create extendable enumerations.
您可以使用项目SuperEnum来创建可扩展的枚举。
/*** my_enum.h ***/
class MyEnum: public SuperEnum<MyEnum>
{
public:
MyEnum() {}
explicit MyEnum(const int &value): SuperEnum(value) {}
static const MyEnum element1;
static const MyEnum element2;
static const MyEnum element3;
};
/*** my_enum.cpp ***/
const MyEnum MyEnum::element1(1);
const MyEnum MyEnum::element2;
const MyEnum MyEnum::element3;
/*** my_enum2.h ***/
class MyEnum2: public MyEnum
{
public:
MyEnum2() {}
explicit MyEnum2(const int &value): MyEnum(value) {}
static const MyEnum2 element4;
static const MyEnum2 element5;
};
/*** my_enum2.cpp ***/
const MyEnum2 MyEnum2::element4;
const MyEnum2 MyEnum2::element5;
/*** main.cpp ***/
std::cout << MyEnum2::element3;
// Output: 3
回答by Haspemulator
Well, if you'll define enum
with the same name in derived class and start it from last item of correspondent enum
in base class, you'll receive almost what you want - inherited enum.
Look at this code:
好吧,如果您enum
在派生类中使用相同的名称定义并从enum
基类中通讯者的最后一项开始,您将获得几乎您想要的 - 继承的枚举。看看这段代码:
class Base
{
public:
enum ErrorType
{
GeneralError,
NoMemory,
FileNotFound,
LastItem
}
}
class Inherited: public Base
{
enum ErrorType
{
SocketError = Base::LastItem,
NotEnoughBandwidth,
}
}
回答by vigilance
As stated by bayda
, enum's don't (and/or shouldn't) have functionality, so I've taken the following approach to your quandary by adapting Mykola Golubyev
's response:
正如 所述bayda
,枚举不(和/或不应该)具有功能,因此我通过调整Mykola Golubyev
的响应对您的困境采取了以下方法:
typedef struct
{
enum
{
ONE = 1,
TWO,
LAST
};
}BaseEnum;
typedef struct : public BaseEnum
{
enum
{
THREE = BaseEnum::LAST,
FOUR,
FIVE
};
}DerivedEnum;
回答by jsadler
Kind of hacky but this is what I came up with if dealing with scoped enums:
有点hacky,但如果处理范围枚举,这就是我想出的:
enum class OriginalType {
FOO, // 0
BAR // 1
END // 2
};
enum class ExtendOriginalType : std::underlying_type_t<OriginalType> {
EXTENDED_FOO = static_cast<std::underlying_type_t<OriginalType>>
(OriginalType::END), // 2
EXTENDED_BAR // 3
};
and then use like:
然后使用像:
OriginalType myOriginalType = (OriginalType)ExtendOriginalType::EXTENDED_BAR;
回答by Moia
This answer is a variant of Brian R. Bondy answer. Since has been requested in a comment I'm adding it as answer. I'm not pointing about if it really worths though.
这个答案是 Brian R. Bondy 答案的变体。由于已在评论中提出要求,因此我将其添加为答案。我不是指它是否真的值得。
#include <iostream>
class Colors
{
public:
static Colors RED;
static Colors GREEN;
operator int(){ return value; }
operator int() const{ return value; }
protected:
Colors(int v) : value{v}{}
private:
int value;
};
Colors Colors::RED{1};
Colors Colors::GREEN{2};
class RGB : public Colors
{
public:
static RGB BLUE;
private:
RGB(int v) : Colors(v){}
};
RGB RGB::BLUE{10};
int main ()
{
std::cout << Colors::RED << " " << RGB::RED << std::endl;
}