C++中类的静态成员

技术交流QQ群:1027579432,欢迎你的加入!

1.Cpp中类的静态成员

  • 可以使用static关键字来把类成员定义为静态的。当我们声明类的成员为静态时,这意味着无论创建多少个类的对象,静态成员都只有一个副本。静态成员在类的所有对象中是共享的。如果不存在其他的初始化语句,在创建第一个对象时,所有的静态数据都会被初始化为零。我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符::来重新声明静态变量从而对它进行初始化,如下面的实例所示:
        #include "iostream"
    
        using namespace std;
    
        class Box{
            public:
                static int count;  // 声明一个静态成员变量!
                Box(double l, double w, double h): length(l), width(w), height(h){
                    cout << "这是Box类对象的构造函数....\n";
                    count++; // 每创建一个Box类的对象时,count增加1
                }
                double getVolume(){
                    return length * width * height;
                }
            private:
                double length;
                double width;
                double height;
        };
        // 静态成员变量要在类外初始化!
        int Box::count = 0;
    
    
        int main(){
            Box box1(3.2, 1.4, 5.5);
            Box box2(6.6, 4.2, 8.7);
            cout << "Box类总共的对象数是: " << Box::count << endl;
            return 0;
        }
    

2.静态成员函数

  • 如果把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符::就可以访问。静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数
  • 静态成员函数有一个类范围,它们不能访问类的this指针。可以使用静态成员函数来判断类的某些对象是否已被创建。静态成员函数与普通成员函数的区别:
    • 静态成员函数没有this指针,只能访问静态成员(包括静态成员变量和静态成员函数);
    • 普通成员函数有this指针,可以访问类中的任意成员,而静态成员函数没有this指针
  • 静态成员函数实例如下:
        #include "iostream"
    
        using namespace std;
    
        class Box{
            public:
                static int count;  // 声明一个静态成员变量!
                Box(double l, double w, double h): length(l), width(w), height(h){
                    cout << "这是Box类对象的构造函数....\n";
                    count++; // 每创建一个Box类的对象时,count增加1
                }
                double getVolume(){
                    return length * width * height;
                }
                // 静态成员函数定义!!!
                static int getCount(){
                    return count;
                }
            private:
                double length;
                double width;
                double height;
        };
        // 静态成员变量要在类外初始化!
        int Box::count = 0;
    
    
        int main(){
            // 在创建对象前输出对象的总数
            cout << "未创建对象前的对象数是: " << Box::getCount() << endl;
            Box box1(3.2, 1.4, 5.5);
            Box box2(6.6, 4.2, 8.7);
            cout << "Box类总共的对象数是: " << Box::getCount() << endl;
            return 0;
        }
    
  • 类的静态成员细节知识
    • 静态成员变量在类中仅仅是声明,没有定义。所以要在类的外面定义,实际上是给静态成员变量分配内存。如果不加定义就会报错,初始化是赋一个初始值,而定义是分配内存
           #include "iostream"
      
          using namespace std;
      
          class Box{
              public:
                  static int count;  // 声明一个静态成员变量!
                  Box(double l, double w, double h): length(l), width(w), height(h){
                      cout << "这是Box类对象的构造函数....\n";
                      count++; // 每创建一个Box类的对象时,count增加1
                  }
                  double getVolume(){
                      return length * width * height;
                  }
              private:
                  double length;
                  double width;
                  double height;
          };
          // 初始化类Box的静态成员 ,其实是定义并初始化的过程
          int Box::count = 0;
          // 也可这样 定义却不初始化
          int Box::count;
          int main(){
              Box box1(3.2, 1.4, 5.5);
              Box box2(6.6, 4.2, 8.7);
              cout << "Box类总共的对象数是: " << Box::count << endl;
              return 0;
          }
      
    • 可以使用静态成员变量清楚了解构造与析构函数的调用情况
          // 可以使用静态成员变量清楚了解构造与析构函数的调用情况
          class Cpoint{
              public:
                  static int value;
                  static int num;
                  Cpoint(int x, int y): xp(x), yp(y){
                      value++;
                      cout << "调用构造: " << value << endl;
                      cout << this->xp << " " << this->yp << endl;
                  }
                  ~Cpoint(){
                      num++;
                      cout << "调用析构: " << num << endl;
                  }
              private:
                  int xp;
                  int yp;
          };
      
          // 静态成员变量初始化
          int Cpoint::num = 0;
          int Cpoint::value = 0;
      
      
          class CRect{
              public:
                  CRect(int x1, int x2): mpt1(x1, x2), mpt2(x1, x2){
                      cout << "调用构造\n";
                  }
                  ~CRect(){
                      cout << "调用析构\n";
                  }
              private:
                  Cpoint mpt1, mpt2;
          };
          CRect p(10, 20);
          cout << "hello world!\n";
      
      • 上述程序的分析:构造p时,先调用CRect的构造函数,在使用初始化列表初始化字段mpt1和mpt2时,又调用Cpoint的构造函数两次;析构p时,先调用CRect的析构函数并输出,然后析构成员mpt1和mpt2,且顺序是先调用mpt2的析构函数,再调用mpt1的析构函数。发现析构的过程和构造过程完全相反
            class Cpoint{
                public:
                    static int value;
                    static int num;
                    Cpoint(int x, int y): xp(x), yp(y){
                        value++;
                        cout << "调用构造: " << value << endl;
                        cout << this->xp << " " << this->yp << endl;
                    }
                    ~Cpoint(){
                        num++;
                        cout << "调用析构: " << num << endl;
                        cout << this->xp << " " << this->yp << endl;
                    }
                private:
                    int xp;
                    int yp;
            };
        
            // 静态成员变量初始化
            int Cpoint::num = 0;
            int Cpoint::value = 0;
        
        
            class CRect{
                public:
                    CRect(int x1, int x2): mpt1(x1, x1), mpt2(x2, x2){
                        cout << "调用构造\n";
                    }
                    ~CRect(){
                        cout << "调用析构\n";
                    }
                private:
                    Cpoint mpt1, mpt2;
            };
            CRect p(10, 20);
            cout << "hello world!\n";
        
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容

  • C++ 面向对象 c++创建对象的时候如果使用new运算符,将会返回返回一个指针,指向堆中的内存地址 类,对象类定...
    小小小8021阅读 285评论 0 0
  • 技术交流QQ群:1027579432,欢迎你的加入! 1.构造函数 类的构造函数是类的一种特殊的成员函数,它会在每...
    CurryCoder阅读 606评论 0 1
  • 第一章 计算机与C++编程简介 C++程序6个阶段编程 ->预处理->编译->连接->装入->执行1.程序在编译器...
    rogertan30阅读 3,635评论 0 1
  • 晚安
    不骄不躁等风来阅读 313评论 0 0
  • 在你身边,默默 在这世界,默默 在他心里,默默 可能 我是存在的 也可能 我是不存在的 我是默默的存在 也默默的不存在
    圆圆小脸阅读 140评论 0 0