• 转:C语言中的static变量和C++静态数据成员(static member)


    转自:C语言中的static变量和C++静态数据成员(static member)

    C语言中static的变量:
    1).static局部变量
            a、
    静态局部变量在函数内定义,生存期为整个程序运行期间,但作用域与自动变量相同,只能在定义该变量的函数内使用。退出该函数后, 尽管该变量还继续存在,但不能使用它。
            b、对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。
    2).static全局变量
            全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。但是他们的作用域,非静态全局变量的作用域是整个源程序(多个源文件可以共同使用); 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件(.h或.cpp)内有效, 在同一源程序的其它源文件中不能使用它(注意,这一点和C++是不同的)。

    关于C语言static变量的理解:

    A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;

    B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;

    C、静态变量和全局变量放在程序的全局数据区,而不是在堆栈中分配,所以不可能导致堆栈溢出;

    D、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题(线程不安全);

    C++中静态数据成员的特点有::

              1、静态数据成员仅仅在初始化时不受访问权限的约束

              2、静态数据成员最好不要在.h文件中进行定义(初始化),而是放在.cpp文件中定义(初始化)

              3、静态数据成员被类的所有对象所共享,包括类的派生类的所有对象;——即派生类和基类共享一个静态成员

              4、静态数据成员的类型可是所属类自己,即在一个类中可以声明该类自己的类型的静态成员对象,但是,不可以定义普通的成员对象,(指针可以)

              5、在const成员函数中,可以修改static成员变量的值。普通成员变量的值,是不能修改的

              6、static成员函数只能访问static成员,不能访问非static成员,并且static成员函数不能定义为virtual、const、volatile 函数

    详细分析如下:

         类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态数据成员。

            和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则注意::仅仅是初始化时不遵守public/protected/private的规则。

            即:如果是private和protected的静态成员,只能通过public的静态成员函数进行调用,而不能通过类名直接访问了。

    1、静态数据成员的定义(初始化)不能在头文件中。 
         静态数据成员实际上是类域中的全局变量。所以,
    静态数据成员的定义(初始化)不应该被放在头文件中。 
        其定义方式与全局变量相同。举例如下: 
    xxx.h文件 
    class base


           private: 
                   static const int _i;           //声明,标准c++支持有序类型在类体中初始化,但vc6不支持。 
    }; 

    xxx.cpp文件 
    const int base::_i=10;                 
    //仅仅在定义(初始化)时不受private和protected访问限制. 

               注:不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。即使加上#ifndef #define #endif或者#pragma once也不行。

    2、静态数据成员   被  的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。举例如下: 
    class base


           public : 
                   static int _num;         //声明 
    }; 
    int base::_num=0;                   //静态数据成员的真正定义 

    class derived:public base


    }; 

    main() 

          base a; 
          derived b; 
          a._num++; 
          cout<<"base class static data number _num is"<<a._num<<endl; 
          b._num++; 
          cout<<"derived class static data number _num is"<<b._num<<endl; 

    // 结果为1,2;可见派生类与基类共用一个静态数据成员。

    3、静态数据成员的类型可以是所属类的类型而普通数据成员则不可以。普通数据成员的只能声明为所属类类型的 指针或引用。举例如下: 

    class base{ 
            public : 
                   static base _object1;                       //正确,静态数据成员 
                   base _object2;                                  //错误 
                   base *pObject;                                  //正确,指针 
                   base &mObject;                               //正确,引用 (引用需要在构造函数的参数初始化列表中初始化,如下:
    };

    这个类要能创建对象,需要定义带有参数初始化列表的构造函数,如下:

    class base{ 
           public : 
                 static base _object1; //正确,静态数据成员 
                 base *pObject;            //正确,指针 
                 base &mObject;         //正确,引用

                 base():mObject(*this){}                
    };

    4、静态数据成员的值在const成员函数中可以被合法的改变,而不破那个数据成员的值,不能在const成员函数中改变。

    #include <iostream>
    using namespace std;

    class Student
    {
     private:
      static int a;
      int b;
     public:
      void change() const;
      void setB(int b);
      int getB();
      static int getA();
    };

    void Student::change() const
    {
              a++;         
     //这个可以,因为a是static成员变量。
              b++;          
    //不可以,因为b是普通成员变量(如果b不是成员变量(是全局变量,普通参数,函数内部定义的临时变量)也可以别修改),且是const函数
    }
    int Student::getA()
    {
             return a;
    }
    void Student::setB(int b)
    {
             this->b = b;
    }
    int Student::getB()
    {
             return b;
    }
    int Student::a = 5;

    int main(int argc,char *argv[])
    {
           Student stu;
           stu.setB(10);
           stu.change();
           cout<<Student::getA()<<endl; 
           cout<<stu.getB()<<endl;
           return 0;
    }

    即:成员函数的const约束,只起作用于类的普通成员变量,对于全局变量,成员函数参数,成员函数内部的临时变量起不到作用。

  • 相关阅读:
    easyui 单元格超出鼠标放上弹出全部
    EasyUI datagrid单元格文本超出显示省略号,鼠标移动到单元格显示文本
    easyui 回车搜索
    js控制easyui文本框例子及控制html例子
    Android错误---NoClassDefFoundError: org.ksoap2.transport.HttpTransportSE
    [Android错误]The literal 100000000000000 of type int is out of range
    Eclipse错误:Conversion to Dalvik format failed with error 1
    Android微信分享音乐加网络图片失败分析
    android.view.WindowManager$BadTokenException异常
    Android错误--Attempted to add application window with unknown token
  • 原文地址:https://www.cnblogs.com/kira2will/p/4100754.html
Copyright © 2020-2023  润新知