基本概念

  • 在说明前加了static关键字

    1. class CRectangle {
    2. private:
    3. int w, h;
    4. static int nTotalArea; // 静态成员变量
    5. public:
    6. CRectangle(int w_, int h_);
    7. static void PrintTotal(); // 静态成员函数
    8. };
  • 普通成员变量每个对象各有一份,但静态成员变量是所有对象共享的,一共只有一份

  • sizeof不计算成员变量
  • 普通成员函数必须具体作用于某个对象,而静态成员函数不是作用于某个对象
  • 静态成员不需要通过对象就能访问,本质上是一个全局变量,即便一个对象也不存在,这个变量也存在
  • 静态成员函数相当于全局函数

    如何访问?

  • 类名::成员名

    • CRectangle::PrintTotal();
  • 对象名. 成员名 & 指针 -> 成员名
    • BUT! 不做用于某个具体对象!
  • 引用. 成员名

接上例

  1. CRectangle::CRectangle(int w_, int h_) {
  2. w = w_; h = h_;
  3. nTotalNumber++;
  4. nTotalArea += w * h;
  5. }
  6. CRectangle::~CRectangle() {
  7. nTotalNumber--;
  8. nTotalArea -= w * h;
  9. }
  10. void CRectangle::PrintTotal() {
  11. cout << nTotalNumber << "," << nTotalArea << endl;
  12. }
  • 静态成员变量必须进行一次声明或初始化,否则编译能通过,链接不能通过

    1. int CRectangle::nTotalNumber = 0;
    2. int CRectangle::nTotalArea = 0;
    3. main() {
    4. cout << CRectangle::nTotalNumber; // 错!私有成员,不能访问!
    5. }
  • 静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数

    • 因为静态成员函数不是作用在具体对象上
      1. void CRectangle::PrintTotal() {
      2. cout << w << "," << nTotalNumber << ...; // wrong!
      3. }
      考虑调用CRectangle::PrintTotal(); 是访问谁呢?
      BUT上面的函数声明有问题!Why?
  • 如果是使用复制构造函数生成一个对象,area和num都没有加,消亡的时候却调用了析构函数,总数减少。

    • 所以写一个复制构造函数就好咯