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

2018-06-05  本文已影响0人  木鱼_cc

在 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静态成员函数

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;
}

上一篇下一篇

猜你喜欢

热点阅读