第8章:structures, unions, and enumerations

来源:互联网 发布:lol网吧代理软件 编辑:程序博客网 时间:2024/04/30 17:15

这一章主要讲了关于structures,unions,和enumerations的一些知识。

structures:

1:我们知道数组是相同类型元素的集合,从最简单定义的角度理解,我们可以认为struct是任意类型元素的集合,默认的访问级别是public。

2:在内存中,struct成员分配地址的顺序是按照成员声明的顺序分配的,然而struct对象的内存大小并不简单是其成员内存大小的和。为了节省分配的内存空间,我们一般是把需要最大内存的类型声明放在第一位,需要最小内存的放在最后,根据内存大小排序来进行声明。但一般来说,我们应该根据可读性来安排成员的声明顺序,除非实在有必要节省空间,我们才将成员类型占用内存的大小从大到小排序来安排成员声明的顺序。

3:我们在上面提过,从最简单定义的角度理解,struct可被认为是任意类型元素的集合。但事实上,struct和class是没有什么区别的,只是struct默认的成员是public,class默认的成员是private。像class一样,struct中不仅能够包含任意类型的元素,还能够有成员函数,同时也能够有构造函数。

4:每个struct都有一个唯一的定义,哪怕他们有相同的成员。如:

struct s1 {int a;};struct s2 {int b;};s1 x;s2 y=x   // error: s1和s2是不同的类型;

enumerations:

有两种枚举类型,一种是c++旧标准定义的enum,一种是c++11新标准定义的enum class。它们有如下不同:

1:枚举成员的作用域不同:

enum枚举成员拥有着和enum相同的作用域(scope),比如假设 enum color { red,black,green};在全局作用域中定义,那么enum中的枚举成员red,black,green作用域也是全局的,当我们想要访问其枚举成员时,可以直接写成red或black或green的形式。

然而对于enum class来说,其枚举成员的作用域仅限于enum class类内,比如假设 enum class color { red,black,green};在全局作用域中定义,但当我们想要访问其枚举成员时,我们必须写成color::red的形式,而不是仅仅写成red的形式。

因此当我们在相同的作用域中定义 多个enum和enum class 时,对于enum来说,它们之间的枚举成员名字一定不能相同,否则会出现编译错误,而enum class之间可以允许有相同的枚举成员名字。比如:

enum Traffic_light { red,black,green};enum Warning { green,yellow,orange,red}; 

如果上面两行代码出现在相同的作用域中,编译器会给出错误信息,指出枚举成员red和green被重新定义了。

enum class Traffic_light { red,black,green};enum class Warning { green,yellow,orange,red};

这两行代码出现在相同作用域中是可行的,因为他们的枚举成员仅仅局限于Traffic_light和Warning作用域中,没有名字冲突。

当然如下的代码出现在相同的作用域中是可行:

enum class Traffic_light {red,black,green};enum Warning{ green,yellow,orange,red};

2:对于enum来说,其枚举成员的值可以隐式地转换成整型值,但是enum class不可以。但无论对于enum还是enum class来说,整型值都不能隐式地转换成枚举成员。但对于这种没有隐式定义的相互转换,我们能够借助static_cast()来显示定义。例子如下:

// examples for enumenum Color { red,black,green};color c0=0     //error, no int->Color implicit conversion;int i1=red    // okay,red is in the scope and converts int;color c1=static_cast<color>(0) //okay。 explicit conversion from int to color.//examples for enum class;enum class Traffic_light { red,black,green};Traffic_light tl1=0; //error, no int->Traffic_light implicit conversion;int i2=Traffic_light::red; // error, no traffic_light::red->int implicit conversion;Traffic_light tl2=static_cast<Traffic_light>(0) //okay. explicit conversion from int to Traffic_lightint i3=static_cast<int>(Traffic_light::red) //okay. explicit conversion from Traffic_light to int.

(3)定义enum时可以允许没有名字,比如

enum { arrow_up=1,arrow_down, arrow_sideways};

一般当我们只需要一系列整型常量,但不需要一个类型去定义变量时,我们可以这样做。当然如果我们想要定义enum class,一定要有名字,否则会出现编译错误。

(4):虽然enum class有着一些严格的性质,但是我们可以把enum class看成一个类,这样我们就可以针对enum class定义重载操作符,这样就大大扩展了enum class的功能。一般来说,我们应该更多地使用enum class而不是enum,这样可以尽可能避免编译错误。

0 0
原创粉丝点击