zoukankan      html  css  js  c++  java
  • C++基础之static关键字

    一、静态变量

    与C语言一样,可以使用static说明自动变量。根据定义的位置不同,分为静态全局变量和静态局部变量
    ⚫ 全局变量是指在所有花括号之外声明的变量,其作用域范围是全局可见的,即在整个项目文件内都有效。使用static修饰的全局变量是静态全局变量,其作用域有所限制,仅在定义该变量的源文件内有效,项目中的其他源文件中不能使用它。
    ⚫ 块内定义的变量是局部变量,从定义之处开始到本块结束处为止是局部变量的作用域。使用static修饰的局部变量是静态局部变量,即定义在块中的静态变量。静态局部变量具有局部作用域,但却具有全局生存期。
    ⚫ 静态局部变量具有局部作用域,但却具有全局生存期。也就是说,静态局部变量在程序的整个运行期间都存在,它占据的空间一直到程序结束时才释放,但仅在定义它的块中有效,在块外并不能访问它。
    ⚫ 静态变量均存储在全局数据区,静态局部变量只执行一次初始化。如果程序未显式给出初始值,则相当于初始化为0;如果显式给出初始值,则在该静态变量所在块第一次执行时完成初始化。

    #include<iostream>
    using namespace  std;
    
    //全局静态变量
    static int glos_s=10;
    //全局变量
    int glos_a=10;
    
    void f(){
        int a=1; //局部变量a
        static int fs=1; //静态局部变量fs,完成初始化。
        a+=2;
        fs+=2;
        glos_s+=10;
        glos_a+=10;
        cout<<"在f中:局部变量a="<<a<<" 静态局部变量fs="<<fs<<" 全局变量glos_a="<<glos_a<< " 全局静态变量glos_s=" <<  glos_s  <<endl;
    }
    int main(){
         f(); //在f中:局部变量a=3 静态局部变量fs=3 全局变量glos_a=20 全局静态变量glos_s=20
         f(); //在f中:局部变量a=3 静态局部变量fs=5 全局变量glos_a=30 全局静态变量glos_s=30
        return 0; 
    }

    二、类中的static

    1、定义类的静态成员

    类的静态成员有两种:静态成员变量和静态成员函数。在类体内定义类的成员时,
    在前面添加static关键字后,该成员即成为静态成员。
    ⚫ 类的静态成员被类的所有对象共享,不论有多少对象存在,静态成员都只有一份保存在公用内存中。对于静态成员变量,各对象看到的值是一样的。
    ⚫ 定义类静态成员变量时,在类定义中声明静态成员变量,然后必须在类体外定义静态成员变量的初值。这个初值不能在类体内赋值。
    ⚫ 给静态成员变量赋初值的格式如下:类型 类名::静态成员变量=初值;
    ⚫ 注意,在类体外为静态成员变量赋初值时,前面不能加static关键字,以免和一般的静态变量相混淆。在类体外定义成员函数时,前面也不能加static关键字。

    2、类静态成员的使用
    访问静态成员时,成员前面既可以用类名作前缀,也可以使用对象名或对象指针作前缀。这与访问类成员时仅能使用对象名或对象指针作前缀是不同的。访问类静态成员的一般格式如下:

    • 类名::静态成员名
    • 对象名.静态成员名
    • 对象指针->静态成员名

    类的静态成员函数没有this指针,不能在静态成员函数内访问非静态的成员,即通常情况下,类的静态成员函数只能处理类的静态成员变量。静态成员函数内也不能调用非静态成员函数。

    #include<iostream>
    
    using namespace  std;
    
    class Student{
        public:
            int id;
            string name;
            static int money;
            static void printlnMoney(Student &stu);    
    };
    //静态成员必须在类体外初始化,并且不能在类体内赋值
    int Student::money=10000;
    //静态成员函数的实现
    void Student::printlnMoney(Student &stu){
        cout << "name:"  << stu.name  <<" money:" << stu.money << endl;
    }
    
    int main(){
        Student stu;
        stu.id=1;
        stu.name="小米";
        //使用对象调用静态成员
        stu.printlnMoney(stu);//name:小米 money:10000
        Student *stu2=new Student();
        stu2->id=1;
        stu2->name="美团";
        //使用指针调用静态成员
        stu2->printlnMoney(*stu2);//name:美团 money:10000
        //使用类名调用静态成员
        Student::money=50000;
        Student::printlnMoney(*stu2);//name:美团 money:50000
        Student::printlnMoney(stu);//name:小米 money:50000
        return 0; 
    }

    3、普通成员与静态成员 

    对于普通成员变量,每个对象有各自的一份,而静态成员变量只有一份,被同类所有对象共享。普通成员函数一定是作用在某个对象上的,而静态成员函数并不具体作用在某个对象上。
    访问普通成员时,要通过“对象名.成员名”等方式,指明要访问的成员变量是属于哪个对象的,或要调用的成员函数作用于哪个对象;
    访问静态成员时,则可以通过“类名::成员名”的方式访问,不需要指明被访问的成员属于哪个对象或作用于哪个对象。
    因此,甚至可以在还没有任何对象生成时就访问一个类的静态成员。非静态成员的访问方式其实也适用于静态成员,也就是可以通过“对象名.成员名”的方式访问,效果和“类名::成员名”这种访问方式没有区别

     在通常情况下,除一种情况外,类的成员函数之间是允许互相调用的。具体来说,静态函数与静态函数之间、非静态函数与非静态函数之间是可以相互调用的,非静态成员函数内可以调用静态成员函数,但静态成员函数内不能调用非静态成员函数

  • 相关阅读:
    使用Perl5获取有道词典释义
    Compress a Folder/Directory via Perl5
    为该目录以及子目录添加index.html
    学习Perl6: slice fastq file
    Javascript Regexp match and replace
    赋值运算符函数
    扑克牌顺子
    翻转单词顺序VS左旋转字符串
    和为S的两个数字VS和为S的连续正数序列
    数组中只出现一次的数字
  • 原文地址:https://www.cnblogs.com/jalja365/p/12987980.html
Copyright © 2011-2022 走看看