美文网首页
八、静态成员变量和成员函数

八、静态成员变量和成员函数

作者: 木鱼_cc | 来源:发表于2018-06-05 14:01 被阅读0次

    在 C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供 所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间 的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。

    1.静态成员变量

    类的静态成员,属于类,也属于对象,但终归属于类。

    //声明
    static 数据类型 成员变量; //在类的内部
    
    //初始化
    数据类型 类名::静态数据成员 = 初值;//在类的外部
    
    //调⽤用
    类名::静态数据成员
    类对象.静态数据成员
    
    
    class AA
    {
       public:
         AA(int a,int b)
          {
               m_a = a;
               m_b = b;
          }
         int getC(){
                cout<<"c = "<<m_c<<endl;
                return m_c;
         }
         static int m_c;//静态的成员变量
           //1.在类的内部声明这个变量 用static
          //静态的成员变量是堆本类共享 的,所有本类中的对象,都是公用一个内存区域,如图1   
    
       private:
         int m_a;
         int m_b;
    }
    
    //2.静态成员变量必须被初始化,在类的外部去写,它是在全局区开辟空间的
    int AA::m_c = 0;
    
    int main(void)
    {
       AA aa1(10,20),aa2(100,200),aa3(1000,2000);
       aa1.getC();//0
       aa2.getC();//0
       aa3.getC();//0
    
    //怎么去修改一个静态的成员变量
       AA::m_c = 200;
       aa1.getC();//200
       aa2.getC();//200
       aa3.getC();//200
    
       return 0;
    }
    
    1.png

    2.静态成员函数

    //声明
    static 函数声明
    
    //调用
    类名::函数调用
    类对象.函数调用
    
    class Student
    {
       public:
        Student(int num,double score){
           m_num = num;
           m_score = score;
           count++;
          sum_score +=score;
       }
    
      static double getAvg(){
         return sum_score/count;
       }
    
       private:
           int m_num;//学号
           double m_score;//成绩
      
          static int count;//记录目前Student类已经创建了多少个学生对象
          static double sum_score;//所有已经定义学生对象的总score和
    };
    
    //在类的外面初始化成员变量
    int Student::count = 0;
    double Student::sum_score = 0.0;
    
    
    int main(void){
        Student s1(1,100);
        Student s2(2,90);
        Student s3(3,80);
       
       //使用一个静态的成员函数
        double avg = Student::getAvg();//可以把他当做一个类的全局函数
        cout<<"平均分为:"<<avg<<endl;
    
    
       return 0;
    }
    

    3.总结

    3.1静态成员变量

    1 static 成员变量实现了同类对象间信息共享。
    2 static 成员类外存储,求类大小,并不包含在内。
    3 static 成员是命名空间属于类的全局变量,存储在 data 区。
    4 static 成员只能类外初始化。
    5 可以通过类名访问(无对象生成时亦可),也可以通过对象访问。

    3.2静态成员函数

    • 静态成员函数的意义,不在于信息共享,数据沟通,而在于管理静态数据成员, 完成对静态数据成员的封装。
    • 静态成员函数只能访问静态数据成员。原因:非静态成员函数,在调用时this 指针被当作参数传进。而静态成员函数属于类,而不属于对象,没有 this 指针。

    4.编译器堆属性和方法的处理机制

    class C1
    {
      public:
         int i;//4
         int j;//4
         int k;//4
    };//12
    
    class C2
    {
      public:
        int i;
        int j;
        int k;
        static int m; //4
    
     public:
        int getK() const{return k;}//4
        void setK(int val) {k = val;}//4
     };
    
    struct S1{
        int i;
        int j;
        int k;
    };//12
    
    struct S2
    {
        int i;
        int j;
        int k;
       static int m;
    };//12?
    
    int main()
    {
      cout<<"c1:"<<sizeof(C1)<<endl;//12
      cout<<"c1:"<<sizeof(C2)<<endl;//12
      cout<<"c1:"<<sizeof(S1)<<endl;//12
      cout<<"c1:"<<sizeof(S2)<<endl;//12
    
      return 0;
    }
    
    通过上面的案例,我们可以的得出:
    C++类对象中的成员变量和成员函数是分开存储的
    
    成员变量:
    普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式
    
    静态成员变量:存储于全局数据区中
    
    成员函数:存储于代码段中。
    
    ---------------------------------------------------------
    1、C++类对象中的成员变量和成员函数是分开存储的。C语言中的内存四区模
    型仍然有效!
    2、C++中类的普通成员函数都隐式包含一个指向当前对象的this指针。
    3、静态成员函数、成员变量属于类
    4、静态成员函数与普通成员函数的区别
      静态成员函数不包含指向具体对象的指针
      普通成员函数包含一个指向具体对象的指针
    
    

    5.强化练习-static仓库进货出货

    某商店经销一种货物。货物购进和卖出时以箱为单位,各箱的重量不一样,因此,商店需要记录目前库存的总重量。现在用C++模拟商店货物购进和卖出的情形

    /*
     static
    */
    
    class Goods
    {
        public:
             Goods(){
               weight = 0;
               next = NULL;
                cout<<"创建了一个货物,重量是0"<<endl;
             }
            //有参数的构造函数
             Goods(int w){
               weight = w;
               next = NULL;
                //每创建一个货物 总重量应该加
              cout<<"创建了一个货物,重量是"<<w<<endl;
               total_weight += w;
              }
    
          //提供一个静态的成员函数来访问静态成员
        static int getTotal(){
               return total_weight;
             }
    
        ~Goods()
        {
           cout<<"删除了一项重量是"<<weight<<"的货物"<<endl;
           total_weight -= weight;
        }
    
    
       //给货物类编程一个链表的节点
         Goods *next;
    
        private:
           int weight;//货物重量
           static int total_weight;//所有货物的总重量
    
    }
    int Goods::total_weight = 0;
    
    //进货的方法
    void buy(Goods* &head,int w)//Goods *的引用就是Goods**
    {
        //创建一个新的货物
        Goods *new_goods = new Goods(w);//通过new在堆上开辟空间,调用了Goods类的有参构造函数
    
        if(head == NULL){//如果head是空
            head = new_goods;
        }
        else{
            //如果head不为空,从head表头添加
            new_goods->next = head;
            head = new_goods;
        }
    }
    
    //出货的方法
    void sale(Goods* &head)
    {
       if(head == NULL){
           cout<<"仓库已经没有货物了"<<endl;
           return ;
        }
       
       Goods *temp = head;
       head = head->next;
       delete temp;
       cout<<"saled"<<endl;
    
    }
    
    
    int main(void)
    {
    
        int choice = 0;
        Goods *head = NULL;   //这是所有货物的表头
    
        do{
         
          cout<<"1 进货"<<endl;
          cout<<"2 出货"<<endl;    
          cout<<"0 退出"<<endl;
          cin>>choice;
    
          switch(choice)
          {
              case 1://进货
                  cout<<"请输入要创建的货物的重量"<<endl;
                   int w;
                   cin>>w;
                   buy(head,w);
                   break;
              case 2://出货
                  sale(head);
                   break;
              case 0:
                   return 0;
                   break;
              default:
                   break;
           }
          cout<<"此时仓库中有"<<Goods::total_weight<<"重量的货物"<<endl;    
         }while(1);
      return 0;
    }
    
    

    相关文章

      网友评论

          本文标题:八、静态成员变量和成员函数

          本文链接:https://www.haomeiwen.com/subject/hempsftx.html