zoukankan      html  css  js  c++  java
  • c++ static

    静态全局变量

    #include <iostream>
    using namespace std;
    
    static size_t ctr = 0;
    size_t count_calls()
    {
        return ++ctr;
    }
    
    int main()
    {
        for(size_t i=0; i < 10; ++i)
        {
            cout << "times:" << count_calls() << endl;;
        }
    }

    特点

    • 变量在全局数据区分配内存
    • 未经初始化的静态全局变量会被程序自动初始化为0
    • 静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的

    结果

    全局变量和全局静态变量的区别

    1)全局变量是不显式用static修饰的全局变量,但全局变量默认是动态的,作用域是整个工程,在一个文件内定义的全局变量,在另一个文件中,通过extern 全局变量名的声明,就可以使用全局变量。
    2)全局静态变量是显式用static修饰的全局变量,作用域是声明此变量所在的文件,其他的文件即使用extern声明也不能使用。
     

    静态局部变量

    #include <iostream>
    using namespace std;
    size_t count_calls()
    {
        static size_t ctr = 0;
        return ++ctr;
    }
    
    int main()
    {
        for(size_t i=0; i < 10; ++i)
        {
            cout << "times:" << count_calls() << endl;;
        }
    }

    特点

    • 该变量在全局数据区分配内存
    • 静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化
    • 静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0
    • 它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束

    结果

     静态函数

    #include <iostream>
    using namespace std;
    static void fn()
    {
        int n = 10;
        ++n;
        cout << n << endl;
    }
    
    int main()
    {
        cout << "first use:" << endl;
        fn();
        cout << "second use:" << endl;
        fn();
    }

    使用静态函数好处

    • 静态函数不能被其它文件所用
    • 其它文件中可以定义相同名字的函数,不会发生冲突

    结果

     类中的静态数据成员

    #include <iostream>
    using namespace std;
    class Myclass
    {
        public:
            Myclass(int va, int vb, int vc);
            void GetSum();
        private:
            int a;
            int b;
            int c;
            static int sum;
    };
    
    int Myclass::sum = 10;
    
    Myclass::Myclass(int va, int vb, int vc)
    {
        a = va;
        b = vb;
        c = vc;
        sum += a + b + c;
    }
    
    void Myclass::GetSum()
    {
        cout << "Sum:" << sum << endl;
    }
    
    int main()
    {
        cout << Myclass::sum << endl;
        Myclass classa(1, 1, 1);
        classa.GetSum();
    
        Myclass classb(1, 1, 1);
        classb.GetSum();
    }
        

    结果

    特点

    • 静态数据成员在程序中也只有一份拷 贝,由所有对象共享(对于非静态数据成员,每个类对象都有自己的拷贝)
    • 静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义
    • 静态数据成员和普通数据成员一样遵从public,protected,private访问规则
    • 静态数据成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式为:数据类型 类名::静态数据成员名 =值

    同全局变量相比,使用静态数据成员有两个优势

    • 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性
    • 可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能

     类中静态成员函数

    #include <iostream>
    using namespace std;
    class Myclass
    {
        public:
            Myclass(int va, int vb, int vc);
            static void GetSum();
        private:
            int a;
            int b;
            int c;
            static int sum;
    };
    
    int Myclass::sum = 10;
    
    Myclass::Myclass(int va, int vb, int vc)
    {
        a = va;
        b = vb;
        c = vc;
        sum += a + b + c;
    }
    
    void Myclass::GetSum()
    {
        cout << "Sum:" << sum << endl;
        cout << "Sum:" << a << endl;
    }
    
    int main()
    {
        Myclass classa(1, 1, 1);
        classa.GetSum();
    
        Myclass classb(1, 1, 1);
        classb.GetSum();
    }
        

    结果

    特点

    • 出现在类体外的函数定义不能指定关键字static
    • 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数(不限制在类中成员)
    • 静态成员函数可以任意地访问静态成员函数和静态数据成员
    • 静态成员函数不能访问非静态成员函数和非静态数据成员
    • this 是缺省的(因为:静态成员函数由于不是与任何的对象相联系)
    • 由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长
    • 不能将静态成员函数定义为虚函数

    一个例子

    #include <iostream>
    #include <vector>
    #include <set>
    using namespace std;
    class A
    {
        public:
            A(int val) : a(val) {};
            static void init_vec(); 
            static void push_a(int val) { vec.push_back(val); }  //static函数可以改变static成员
            static void print_vec()
            {
                cout << "hello" << vec.size() << endl;
                for(vector<int>::iterator beg = vec.begin(); beg != vec.end(); ++beg)
                    cout << *beg << endl;
            }
        private:
            static vector<int> vec;
            int a;
    };
    
    vector<int> A::vec;   //在类的外边定义
    
    int main()
    {
        A a(3);
        a.push_a(34);
        a.push_a(45);
        a.push_a(5);
        a.print_vec();
    }

     继承

    #include <iostream>
    #include <string>
    using namespace std;
    
    class base
    {
        public:
            static void print_1() { cout << "hello:" << ++val << endl; }
            static int val;
    };
    int base::val = 1;
    class derived :public base
    {
    };
    
    
    int main()
    {
        base b;
        derived d;
        base::print_1();
        derived::print_1();
        b.print_1();
        d.print_1();
    }

    结果

  • 相关阅读:
    .net中Timer的使用
    计算日期的神器
    求全排列函数next_permutation
    各种排序
    求最大字段和
    炸弹时间复位
    最少步数,广搜
    数据
    水池数目
    最大岛屿
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/3236606.html
Copyright © 2011-2022 走看看