• 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
    声明:本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此声明,且在文章明显位置给出本文链接,否则保留追究法律责任的权利。
    签名:顺序 选择 循环
  • 相关阅读:
    Docker制作tomcat镜像,发布镜像
    DockerFile
    Docker容器数据卷
    Docker镜像
    Docker部署nginx,tomcat,es,可视化
    java 使用 poi 更新 ppt 中图表的数据
    require.js与IDEA的配合
    html中require.config 缓存问题
    mongodb 更新嵌套数组的值
    java poi ppt 接口的基本操作
  • 原文地址:https://www.cnblogs.com/Braveliu/p/2840489.html
Copyright © 2020-2023  润新知