static关键字(C/C++ 语言中的作用)

【1】类中静态成员注意事项

(1)类中静态成员分为 静态数据成员 和 静态成员函数。

(2)静态数据成员与全局对象的区别:

  <1> static成员的名字是在类的作用域中,可以避免命名冲突。

  <2> static数据成员可以是私有成员,而全局对象不可以。

  <3> 便于阅读维护程序:static成员是与特定的类相关联的。

(3)static成员遵循正常的访问规则。

(4)类中static数据成员独立于该类的任意对象而存在。

(5)在成员声明前加上static关键字将成员设为所谓的静态。

(6)类中static成员函数与一般的普通成员函数最大的区别在于不存在this指针。因为这个函数是与类相关的函数,而不是与某一个对象相关。

(7)声明函数时在前面加关键字static,当在类外实现这个函数时,不允许加关键字。

(8)可以通过作用域操作符直接调用static成员函数。或者类的对象,引用或指向类对象的指针间接的调用static函数。

(9)static成员不是任何对象的组成部分,所以static成员函数不能被声明为const。(函数声明为const是对函数this指针的进一步限定,而

  static成员函数本身就不存在this指针,所以再加const是没有意义的)

(10)static成员函数不可以被声明为虚函数。虚函数是为实现多态的一种特殊的成员函数,因为static函数没有this指针,因此是没有意义的。

(11)static数据成员可以声明为任意类型:常量、引用、数组、类类型等等。

(12)static数据成员必须在类的定义体外部定义。

  1、静态数据成员声明,相关示例代码如下1:

 1 class B
 2 {
 3 };
 4 class  A
 5 {
 6 public:
 7     static  A  a;         //OK
 8     //A a1;               //error!!!
 9     static int * ip;      //OK
10     static A *p;          //OK
11     static A & a2;        //OK
12     static  int  b;       //OK
13     static  int &c;       //OK
14     static  int ar[10];   //OK
15     static  B d;          //OK
16     static const int n;   //OK
17 };

  2、静态成员函数声明及访问,相关示例代码如下:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class TestStatic
 5 {
 6 public:
 7     void normal()
 8     {
 9         cout << "TestStatic::normal()" << endl;
10         print(100);
11     }
12 
13     static void print(int nValue)
14     {
15         cout << "TestStatic::print(" << nValue <<")" << endl;
16         // normal();  // error! 非法调用
17     }
18 };
19 
20 void main()
21 {
22     TestStatic objSta; // 对象
23     objSta.print(1);
24     objSta.normal();
25 
26     TestStatic& refObj = objSta;  // 引用
27     refObj.print(2);
28     refObj.normal();
29 
30     TestStatic* pSta = &objSta; // 指针
31     pSta->print(3);
32     pSta->normal();
33 
34     TestStatic::print(4);
35     // TestStatic::normal();
36     // error! a nonstatic member reference must be relative to a specific object
37 
38     const TestStatic objConst;
39     objConst.print(5);
40     // objConst.normal();
41 
42     system("pause");
43 }
44 /* run out
45 TestStatic::print(1)
46 TestStatic::normal()
47 TestStatic::print(100)
48 TestStatic::print(2)
49 TestStatic::normal()
50 TestStatic::print(100)
51 TestStatic::print(3)
52 TestStatic::normal()
53 TestStatic::print(100)
54 TestStatic::print(4)
55 TestStatic::print(5)
56 请按任意键继续. . .
57 */

【2】C语言中static的作用

第一、修饰局部变量。static修饰的局部变量只执行一次初始化,且延长了局部变量的生命周期,直到程序运行结束以后才释放。

  static修饰的局部变量存放在全局数据区的静态变量区。初始化的时默认值为0;

第二、修饰全局变量。static修饰的全局变量只能在本文件中访问,不能在其它文件中访问,即便是加extern外部声明也不可以。

第三、修饰函数。若static修饰一个函数,则这个函数的只能在本文件中调用,不能在其他文件被调用。即具有文件作用域。

(1)不想被释放的时候,可以使用static修饰。比如修饰函数中存放在栈空间的数组。如果不想让这个数组在函数调用结束释放可以使用static修饰。

(2)考虑到数据安全性(当想要使用全局变量的时候应该先考虑使用static)。

综上所述,从更深层次思考,不加static意味着external链接属性,可能在其它编译单元有定义,或被其它编译单元使用,由于某种需要,一般会有一个跳转表。

而static只在本编译单元用,所以没有跳转表。也就是说,不加static的会执行一个jmp然后再到函数体代码,而static的会直接执行。

为什么要有一个表呢?正是实现多编译单元的相互作用。比如函数在A中定义,在B中调用,于是调用的代码只需要走到跳转表就行。

Good  Good  Study, Day  Day  Up.

顺序  选择  循环  总结

作者:kaizen
声明:本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此声明,且在文章明显位置给出本文链接,否则保留追究法律责任的权利。
签名:顺序 选择 循环
原文地址:https://www.cnblogs.com/Braveliu/p/2840489.html