笔试题集锦----static关键字
简约、高效、实践。
转载请标明出处
在说static关键字作品之前,先明确一下几点。有关一下几点的详细阐述,参考
1、作用域
有6种作用域,分别为全局作用域、局部作用域、语句作用域、类作用域、命名空间作用欲和文件作用域。
2、内存分配的种类 (详见http://www.cnblogs.com/SaveDictator/articles/7266247.html)
堆、栈、自由存储区、全局/静态存储区和常量存储区
static关键字改变了存储方式(位置)以及可见性。
下面就以普通和用static两种分别说明
1、普通局部变量的作用域只是局部的,内存由栈负责,出了函数体外生命周期就结束了;static局部变量的作用域仍是局部,但在静态存储区分配内存,使得它在程序运行的整个阶段都是存在的,只有程序结束时生命周期才结束,不过它只是对定义自己的函数可见。
2、普通全局变量和静态全局变量的作用域都是全局的,内存也都在全局/静态存储区分配,生命周期伴随着整个程序。它俩的区别在于:普通全局变量的可见性是整个源程序(在其它源文件中可以通过extern关键字使用),但是静态全局变量只是在当前源文件是可见的。
下面重点说静态成员变量和成员函数
3、静态成员变量
静态成员不能在类内初始化,因为类的声明并没有为它分配内存,只有在创建对象时才会申请内存,但是有一个特例----静态整型(包括Int和char)成员常量。例如在类内static const int a = 5; static const char c = 's'; 注意,静态成员变量的初始化格式 类型 类名::变量名 = 值(int Base::a = 5;)。
静态成员变量的类型可以是所属类的类型,普通的成员变量不行,普通的成员变量只能声明所属类的指针或者引用。
4、静态成员函数
静态成员函数使得在类中只存在一份存在,所有类对象都共享它,静态成员函数中不包含this指针。
静态成员函数可以直接通过 类名::函数名()调用,无需创建类的实例。
静态成员函数不能直接访问类的非静态成员(因为函数内没有this指针),可以通过传入类的变量来访问非静态成员;但是可以直接访问静态成员。
注意:
1、静态数据成员要保证在程序开始运行时就存在。因为函数都是在程序中调用,所以不能在任何函数中分配以及初始化静态数据成员。
2、不要在头文件中定义(初始化)静态数据成员,这样会引起重定义的错误,即便是采用了#ifndef ..#endif类似的宏。
3、不能将静态成员函数定义为虚函数(为什么?)
第一,虚函数必须根据类的实例才能确定调用哪一个虚函数,也就是说依据类的对象;但是静态成员不属于对象,属于类。这显然是不行的
第二,虚函数依靠vptr和vtable来处理。vptr是一个指针,指向保存虚函数地址的vtable.在类的构造函数中创建生成,并且只能用this指针来访问它,而静态函数不包含this指针。
4、可以在派生类中定义一个与基类一样的静态变量,以用来屏蔽基类的影响。我们说静态成员为父类和子类共享,但 我们有重复定义了静态成员,这会不会引起错误呢?不会,因为编译器采用命名粉碎规则(name-mangling)生成唯一标识。
延伸:
1、如果函数需要返回局部指针,可以用static来修饰;否则将会得到错误的指针。

浙公网安备 33010602011771号