(一一九)类作用域

来源:互联网 发布:布鲁克大学 知乎 编辑:程序博客网 时间:2024/05/17 06:39

变量、函数具有不同的作用域,C++的也引入了一种新的作用域:类作用域

 

在类中定义的名称(如类数据成员和类成员函数名)的作用域,都为整个类,作用域为整个类的名称,在该类之中是已知的,在类外是不可知的(如私有成员变量、公有成员变量和函数也算,因为需要使用作用域解析运算符才能调用)。

 

因此,可以在不同类中使用相同的类成员名而不会引起冲突(例如man类里有一个int a,而player类里也有一个int a,这2个是不会冲突的)。

 

在类声明或成员函数定义中,可以使用未修饰的成员名称(未限定的名称)。

 

以上大概意思就是,类里面的变量、函数名,可以随便起,只要别和同一个类里面的冲突就行(也不能起例如int int这样变量名),他和类外的名字是不会冲突的。

 

 

 

当常量的作用域为类时:

当需要在类中,声明一个数组时(例如是一个有4个元素的int数组),假如若需要给这个数组的成员个数,使用常量来代替。

 

一般在类外,我们是这样做的,首先,使用const int M=4; 这样创建一个常量M(其值为4),然后,使用int b[M]; 创建一个有4个元素的int数组b

 

但是,在类内,是不可以这么做的。

 

原因在于,声明一个类时,实际上是没有创建类对象,只是描述的对象的形式。只有在创建对象时,例如 man a; 时,调用默认构造函数,来创建一个类对象a。但在创建对象a之前,是没有用于存储其的空间的。

 

而函数不同,函数在创建时,是有其内存地址的(所以才有函数指针,指向某个函数)。因此函数内部创建一个常量,是有存储这个常量的空间的。

 

 

为了解决在类中创建一个符号常量的问题,有两个办法:

使用枚举。在类中声明一个枚举,然后给枚举的成员赋值。

声明枚举,例如:enum{M=4};

使用枚举,例如:int b[M];

综合起来:

enum { M = 4 };

int b[M];

之后,就可以用枚举变量M来代表常量4

 

使用没有链接性的静态常量。我们知道,静态常量的持续性是从声明时,一直到程序结束。因此,我们创建一个作用域为类的静态变量,就可以解决这个问题。

因为是只在类中起效,无需在文件中起效,所以创建方法类似在函数内部创建链接性为内部的静态变量,如:

static const int M = 10;

int b[M];

这个时候,M被保存在用于存储静态变量的内存之中(而不是存储在对象之中)。因此,int b[M]就可以调用静态常量M了。

 

 

 

 

作用域内枚举(C++11):

假如有两个枚举,他们都有一个叫做first的成员,如:

enum aa first ,secondthird };

enum bb { firstsecondthird };

这种情况下,编译器会提示这样声明是有错的。原因在于,他们有着同名的枚举成员(共3个),发生了名称冲突的问题。

 

而类可以解决这个问题,C++11提供了一种新枚举,其枚举量的作用域为类,声明方法如下:

enum class aa{first ,second,third};//这是一种新枚举,枚举的作用域为类。

 

这种作用域为类的枚举,具有很多特点,如代码:

#include<iostream>#include<string>int main(){using namespace std;enum class aa{first ,second,third};//这是一种新枚举,枚举的作用域为类。enum bb { first, second, third };aa q = aa::first;//需要用作用域解析运算符bb w = second;//int e = q; //这样的代码是不支持的int r = w;if (r < third)//r和third是作用域不是类的枚举bb的成员cout << "1" << endl;//if (r<aa::third)//这个也是不行的//if (r < q)cout << "2" << endl;//这个也是不行的if (r<int(aa::third))//只有被显式转换后——int(aa:third) ,才能用作一个整型cout << "2" << endl;system("pause");return 0;}

总结:

①声明时,需要在enum和枚举名前,加入class,如:

enum class aa{first ,second,third};

 

②在使用这个作用域为类的枚举时,需要使用作用域解析运算符,如:

aa::first

但这种用法,不能直接将其赋值给一个int值,例如:int q=aa::first这样是不可以的。只能赋给类型为这种枚举名的变量,例如:

aa q = aa::first;

 

③若要使用这种枚举成员,不能像普通枚举那样,直接引用变量名,而是需要通过显式类型转换才能够使用,如:

int(aa::third)

 

 

另注:书中注明C++11作用域内枚举的底层类型可以被修改,如默认为int类型,使用enum class : short pizza { small,large };可以修改常规枚举的底层类型。

但我个人使用的Visual Studio 2015,是无法实现的,不知为何。


0 0
原创粉丝点击