(五)类作用域
1.全局作用域和局部作用域。
全局作用域可以在文件声明之后的任何位置使用,也可以在另一个文件中使用,但加extern声明(这是可以的,但现在一般要使用名称空间的写法,名称空间其实跟全局变量的名称差不多,但是更规范。如同要使用extern一样,要使用名称空间,需要使用using声明或using编译指令,或者::作用域解析运算符)。局部作用域只是在代码块或函数内部起作用。函数只能声明为全局作用域,不能是局部作用域。
2.c++引入了新的类作用域。
类中定义的名称的作用域为整个类的内部,不论是公有成员还是私有成员。所以,只能通过对象来调用类的成员。也就是说,只有在类声明和类成员函数的定义中,才能使用未经修饰的类成员名称。在类外,要使用类的成员的时候,就要使用作用域解析运算符::,直接成员运算符.,间接成员运算符->。
静态的类成员(包括常量和变量)和静态类成员函数都可以在没有对象的时候直接调用(当然也可以通过对象调用),但是要加上作用域解析运算符。静态的成员从源代码编译开始到再次编译为止,编译了之后程序就不再变化,运行程序的时候加载到内存中,因此生命周期是程序开始运行开始到整个程序运行结束为止。
3.作用域为类的常量
在类中直接用const创建一个常量是行不通的,因为类只是数据类型的描述,因此在创建对象之前,并没有存储数据的空间。这可以用两种方法来解决这个问题:一种是声明enum枚举类型的常量,也就是为整型常量提供了一个符号名称,enum{Months=12};double costs[Months];值得注意的是用这种形式创建的符号常量并不会创建类数据成员,所有的对象中都不包含它,作用域为类的代码中只要遇到这个枚举Months时候,都会用12来代替它。这里我们仅仅是为了创建符号常量,并不是为了创建变量,因此不需要枚举名。另一种方法是使用静态变量,也就是static关键字,static const int Months=12;该常量与其他静态变量存储在一起,而不是存储在对象中,静态类成员。被所有的类对象所共享。
类的数据成员有很四种,第一是普通的变量,需要在创建对象的时候来初始化;第二是静态数据成员,需要在类外实现初始化,编译源程序的时候完成初始化,此后一直存在;第三个是类内普通的常量,也是需要在创建对象的时候初始化(但是不能在类定义的时候初始化),创建完成后这个常量将不会改变;第四个是静态类常量,可以在定义的时候初始化,编译完成后一直存在在程序内,被所有的对象所共享。也就是说静态的成员都需要在定义的时候初始化,但普通的静态类成员需要在类声明之后再初始化,而静态类常量在类声明的时候就可以直接初始化了。(目前c++11可以在类内进行普通变量的初始化,但其实是默认参数的一种特殊形式,创建对象的时候如果不对其进行处理就会以类内初始化的值进行初始化)。
4.作用域内枚举
也就是相当于将枚举量加上了一个前缀,其用途其实和名称空间差不多。用法是在传统的emum后面加上class或struct(一般用class),并且枚举类型名一定要有,比如enum class egg{small,middle,big},之后我就可以使用egg::small来使用small,而不会与其他枚举值发生冲突。另外还要注意的是,这种作用域枚举值不会隐式地转换为整型(也就是说不可以赋值给整型或者进行比较运算,但是可以进行强制类型转换);而且可以指定枚举类型使用的底层类型(c++11规定枚举类型的底层类型为int),比如enum class :short egg{small,middle,big};或者enum :short egg{small,middle,big};(c++11也可以用于普通枚举,并且只能是各种整型)指定枚举类型的底层实现是short。
5.抽象数据类型
抽象数据类型ADT(abstract data type)也就是通过通用的方式来描述数据类型,而没有引入语言及实现细节。类和对象可以很方便的实现抽象数据类型的任务。类模板的功能可以将存储的数据类型和类设计隔离开来。

网友评论