zoukankan      html  css  js  c++  java
  • C++类静态成员与类静态成员函数

    当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少类对象无关。静态方法就是与该类相关的,是类的一种行为,而不是与该类的实例对象相关。

        静态数据成员的用途之一是统计有多少个对象实际存在。
        静态数据成员不能在类中初始化,实际上类定义只是在描述对象的蓝图,在其中指定初值是不允许的。也不能在类的构造函数中初始化该成员,因为静态数据成员为类的各个对象共享,否则每次创建一个类的对象则静态数据成员都要被重新初始化。
        静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值。
        静态成员的值对所有的对象是一样的。静态成员可以被初始化,但只能在类体外进行初始化。
        一般形式:
        数据类型类名::静态数据成员名=初值
        注意:不能用参数初始化表对静态成员初始化。一般系统缺省初始为0。
     
        静态成员是类所有的对象的共享的成员,而不是某个对象的成员。它在对象中不占用存储空间,这个属性为整个类所共有,不属于任何一个具体对象。所以静态成员不能在类的内部初始化,比如声明一个学生类,其中一个成员为学生总数,则这个变量就应当声明为静态变量,应该根据实际需求来设置成员变量。
     
    #include "iostream"
    using namespace std;
    class test
    {
    private:
         int x;
         int y;
    public:
         static int num;
         static int Getnum()
         {
              x+=5;   // 这行代码是错误的,静态成员函数不能调用非静态数据成员,要通过类的对象来调用。
              num+=15;
              return num;
         }
    };
    int test::num = 10;
    int main(void)
    {
         test a;
         cout<<test::num<<endl;        //10
         test::num = 20;
         cout<<test::num<<endl;        //20
         cout<<test::Getnum()<<endl;   //35
         cout<<a.Getnum()<<endl;       //50
         system("pause");
         return 0;
    }

      通过上例可知:  x+=5;   // 这行代码是错误的

        静态函数成员必须通过对象名来访问非静态数据成员。
        另外,静态成员函数在类外实现时候无须加static关键字,否则是错误的。
        若在类的体外来实现上述的那个静态成员函数,不能加static关键字,这样写就可以了:
         int test::Getnum()
         {
           .........
         }
    1、static成员的所有者是类本身和对象,但是多有对象拥有一样的静态成员。从而在定义对象是不能通过构造函数对其进行初始化。
    2、静态成员不能在类定义里边初始化,只能在class body外初始化。
    3、静态成员仍然遵循public,private,protected访问准则。
    4、静态成员函数没有this指针,它不能返回非静态成员,因为除了对象会调用它外,类本身也可以调用。
     

    静态成员函数可以直接访问该类的静态数据和函数成员,而访问非静态数据成员必须通过参数传递的方式得到一个对象名,然后通过对象名来访问。

    class Myclass
    {
    private:
            int a,b,c;
            static int Sum;    //声明静态数据成员
    public:
            Myclass(int a,int b,int c);
            void GetSum();
    };
    int Myclass::Sum=0;       //定义并初始化静态数据成员
    Myclass::Myclass(int a,int b,int c)
    {
            this->a=a;
            this->b=b;
            this->c=c;
            Sum+=a+b+c;
    }
    void Myclass::GetSum()
    {
            cout <<"Sum=" <<Sum <<endl;
    }
    int main(void)
    {
            Myclass me(10,20,30);
            me.GetSum();
            system("pause");
            return 0;
    }

    由上例可知,非静态成员函数可以任意地访问静态成员函数和静态数据成员。
    非静态成员函数Myclass(int a,int b,int c)和GetSum()都访问了静态数据成员Sum。
    静态成员函数不能访问非静态成员函数和非静态数据成员。

    关于静态成员函数,可以总结为以下几点:
    出现在类体外的函数定义不能指定关键字static;
    静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
    非静态成员函数可以任意地访问静态成员函数和静态数据成员;
    静态成员函数不能访问非静态成员函数和非静态数据成员;
    由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
    调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,
    当同一类的所有对象使用一个量时,对于这个共用的量,可以用静态数据成员变量,这个变量对于同一类的所有的对象都取相同的值。静态成员变量只能被静态成员函数调用。静态成员函数也是由同一类中的所有对象共用。只能调用静态成员变量和静态成员函数。

  • 相关阅读:
    笨方法学python中执行argv提示ValueError: not enough values to unpack (expected 4, got 1)
    VMware workstation安装
    Redis bigkey分析
    MySQL drop table 影响及过程
    MySQL 大表硬连接删除
    ES elasticsearch 各种查询
    ES elasticsearch 各种聚合
    ES elasticsearch 聚合统计
    ES elasticsearch 实现 count单字段,分组取前多少位,以地理位置中心进行统计
    MySQL行溢出、varchar最多能存多少字符
  • 原文地址:https://www.cnblogs.com/MATU/p/3818163.html
Copyright © 2011-2022 走看看