如何在类内部定义枚举并从外部使用它
Posted
技术标签:
【中文标题】如何在类内部定义枚举并从外部使用它【英文标题】:how to define an enumeration inside a class and use it from the outside 【发布时间】:2011-06-18 21:48:20 【问题描述】:只是因为我不知道在我的 c++ 书中或在 google 上的确切位置。我如何在一个类中实际定义一些枚举(在本例中为 left=1, right=2, top=3, bottom=4
)。我希望能够将此枚举作为参数而不是整数传递给成员函数,因此在外部使用枚举...
有什么方法可以做到这一点,还是有更好的方法可以使枚举只针对该类?
这里的代码不起作用,出于某种原因说enum mySprite::<unamed> myySprite::side member mySprite "mySprite::side" is not a type name
:
class mySprite : public sf::Sprite
public:
enumleft=1, right=2, top=3, bottom=4 side;
float GetSide(side aSide)
switch(aSide)
// do stuff
;
;
【问题讨论】:
遗憾的是,当您无法更改定义mySprite
的头文件时,没有一个答案解释了如何键入它。它来自第 3 方。另见c++ typedef another class's enum?
【参考方案1】:
让您的代码工作所需的最简单的更改是:
class mySprite : public sf::Sprite
public:
enum side left=1, right=2, top=3, bottom=4 ;
float GetSide(side aSide)
switch(aSide)
// do stuff
// add breaks; as appropriate
case left:
case right:
case top:
case bottom:
;
你也可以这样做:
typedef enum left = 1, right, top, bottom side;
这意味着为您的 mySprite
类定义一个匿名枚举类型,并使 side
成为一个别名,从而有效地完成与上述代码相同的事情。为了简洁起见,只需要为第一个枚举值分配一个起始整数。除非您明确指定其他值,否则该点之后的所有值都被理解为每次递增 1。
【讨论】:
+1,至少这个在语法上是正确的! (顺便说一句,第三种选择是:typedef enum side left=1, right, top, bottom side;
虽然这是第三种选择,但它在 C++ 中也是多余的。从技术上讲,typedef 本身在 C++ 中是多余的(在这种情况下),但它最终并不重要。无论哪种方式,编译器都应该足够聪明以理解它。 :)
@david 我很惊讶 OP 接受了一个语法错误的答案。一个兼容的编译器只会拒绝该代码并给他更多的错误来处理。
@Chrono Kitsune:这不是完全多余的,只是枚举名称或 typedef 之间存在差异。 C 和 C++ 查找之间的区别在于,在通用标识符空间中找不到名称后,在 C++ 中会检查用户定义类型标识符空间。如果您有兴趣,我可以挖掘更长的解释(或在 SO 中找到一个)
不,谢谢。我相信你是完全正确的。毕竟,按照你说的去做是有意义的。谢谢你提供的详情。 :)【参考方案2】:
我认为这个例子说明了一切:
class A
public:
enum directions top, left, right, bottom ; // directions is the type
// of the enum elements
void f(directions dir)
if (dir == left)
// ...
else
// ...
;
A object;
object.f(A::top);
【讨论】:
不,它没有,因为枚举默认是私有的:) 呃,让我到了那里,但是哈哈,你忘了我在课程的末尾忘记了一个分号(现在已经删掉了)。 另外,由于您使用的是枚举,您可能希望使用switch
而不是if
。
Space_C0wb0y:不相关且不重要。
@nightcracker:语法错误,您在类中声明了一个未命名枚举类型的单个成员 directions
。函数 void f( directions );
不正确,因为 directions
不是类型。您可能的意思是:enum directions ... ;
【参考方案3】:
您需要将其定义为一种类型,以便在类之外使用它和/或对参数进行强类型化。否则简单定义为int
,其访问修饰符也必须是public:
class foo
public:
typedef enum DIRECTION
LEFT = 1,
RIGHT,
TOP,
BOTTOM,
;
void SetDirection(foo::DIRECTION dir)
_direction = dir;
//...
protected:
//...
private:
foo::DIRECTION _direction;
//...
;
int main()
//...
foo bar;
bar.SetDirection(foo::BOTTOM);
//...
【讨论】:
@Casey,除了不需要之外,它还缺少类型定义的名称。您应该使用:enum DIRECTION ... ;
或 typedef enum DIRECTION ... XXX;
,其中 XXX
可能是 DIRECTION
或您想要提供的任何其他名称,但 typedef 语法 需要该名称。
@Lutz:我不知道是谁告诉你的,但所有 typedef 需要的是一个类型,即“enum”和同义词,即“DIRECTION ... ”。您所指的“XXX”是可以创建的可选变量。如果没有使用它并像示例中那样留空,则不会创建任何变量。
@Casey:XXX
不是可选变量的名称,而是 typedef-name (§7.1.3),它是新的 别名类型的名称。我已经在三个编译器(g++4.2、clang++ 和 comeau)中检查了代码,其中两个 warn 但都接受了代码。如果存在typedef
,我无法确认类型定义中是否需要typedef-name,但由于它被编译器接受,因此它可能是可选的。有趣的是,警告是:warning: typedef requires a name,我认为如果它是required,如果缺少它应该是一个错误
idk 但是这段代码在 msVS++ 中对我有用....会出现其他问题吗?以上是关于如何在类内部定义枚举并从外部使用它的主要内容,如果未能解决你的问题,请参考以下文章