C++类中static成员使用

来源:互联网 发布:游戏手柄软件下载 编辑:程序博客网 时间:2024/06/05 00:44
    在C++中,static成员属于整个类而不是某个对象。不管类创建了多少对象,static成员只存储一份供所有对象使用。    在使用static成员时,对于它的声明、初始化和使用经常感到困惑,在此结合例子说明,希望能加深读者对于static成员的理解。    类中static成员有两种,一是static成员变量,一种是static成员函数。首先,先分析一下static成员变量。

第一个例子:static、static const、const和枚举的初始化

  1. class classA
  2. {
  3. const int ciNum;
  4. enum{eNum=10}; //枚举在类声明时初始化
  5. int arr[eNum];
  6. public:
  7. classA():ciNum(10){} //const变量只能在构造函数初始化列表中初始化
  8. static int siNum;
  9. static const int sciNum=10; //static const可在类声明时初始化
  10. static const int sciNumOut;
  11. };
  12. int classA::siNum=10; //static变量必须在类外面初始化,但不需要加static修饰符
  13. const int classA::sciNumOut=10; //static const可在类外面初始化,不加static,但要加cosnt
  14. int main()
  15. {
  16. cout<<classA::siNum<<endl;
  17. cout<<classA::sciNum<<endl;
  18. cout<<classA::sciNumOut<<endl;
  19. return 0;
  20. }

编译通过 
结论1:枚举在类声明时初始化;static const可在类声明中初始化,也可在类外面初始化;const和引用在构造函数初始化列表中初始化;static成员变量只能在类外面初始化

第二个例子:static成员变量的引用

  1. class classA
  2. {
  3. public:
  4. static int pub_siNum;
  5. };
  6. class classB: public classA{};
  7. int classA::pub_siNum=10;
  8. int main()
  9. {
  10. classA tempA;
  11. classB tempB;
  12. cout<<classA::pub_siNum<<endl;
  13. cout<<tempA.pub_siNum<<endl;
  14. cout<<classB::pub_siNum<<endl;
  15. cout<<tempB.pub_siNum<<endl;
  16. return 0;
  17. }

编译通过 
结论2:公有static成员变量可以通过类名或者类对象调用,方式为“类名+::”或者“对象名+.”或“对象指针+->”;公有继承类的调用方式与基类相同

  1. class classA
  2. {
  3. static int pri_siNum;
  4. };
  5. class classB: public classA{};
  6. int classA::pri_siNum=10; //初始化方式同公有static成员变量
  7. int main()
  8. {
  9. classA tempA;
  10. classB tempB;
  11. cout<<classA::pri_siNum<<endl;
  12. cout<<tempA.pri_siNum<<endl;
  13. cout<<classB::pri_siNum<<endl;
  14. cout<<tempB.pri_siNum<<endl;
  15. return 0;
  16. }

编译出错:error C2248: “classA::pri_siNum”: 无法访问 private 成员(在“classA”类中声明) 
结论3:私有static成员不能被类外部函数访问,也不能被对象访问,对于继承类也是如此

接下来分析一下static成员函数: 
第一个例子:static成员函数的引用

  1. class classA
  2. {
  3. public:
  4. static void init(){}
  5. };
  6. class classB: public classA{};
  7. int main()
  8. {
  9. classA tempA;
  10. classB tempB;
  11. classA::init();
  12. tempA.init();
  13. classB::init();
  14. tempB.init();
  15. return 0;
  16. }

编译通过 
结论1:公有static成员函数可以通过类名或者类对象调用,方式为“类名+::”或者“对象名+.”或“对象指针+->”;公有继承类的调用方式与基类相同。而私有static成员函数不能通过类或对象调用

第二个例子,在类的static成员函数中使用类的非static成员

  1. class classA
  2. {
  3. public:
  4. int iNum;
  5. static void output()
  6. {
  7. cout << ++siNum;
  8. cout << iNum;
  9. }
  10. private:
  11. static int siNum;
  12. };
  13. int classA::siNum=10;
  14. int main()
  15. {
  16. classA tempA;
  17. tempA.iNum=10;
  18. tempA.output();
  19. return 0;
  20. }

编译出错:error C2597: 对非静态成员“classA::iNum”的非法引用 
因为static成员函数属于整个类,在类实例化对象之前就已经分配空间了,而类的非static成员必须在类实例化对象后才有内存空间,所以这个调用就出错了,就好比没有声明一个变量却提前使用它一样。 
结论2:static成员函数可以引用static成员变量,但不能引用非static成员

第三个例子,在类的非static成员函数中使用类的static成员

  1. class classA
  2. {
  3. public:
  4. int iNum;
  5. void output()
  6. {
  7. cout << ++siNum;
  8. cout << iNum;
  9. }
  10. private:
  11. static int siNum;
  12. };
  13. int classA::siNum=10;
  14. int main()
  15. {
  16. classA tempA;
  17. tempA.iNum=10;
  18. tempA.output();
  19. return 0;
  20. }

编译通过 
结论3:类的非static成员函数可以引用static成员

第四个例子:static成员函数和非static成员函数的相互引用

  1. class classA
  2. {
  3. public:
  4. void outPut()
  5. {
  6. };
  7. static void staticOutput()
  8. {
  9. outPut();
  10. };
  11. static void staticOutput2()
  12. {
  13. };
  14. void outPut2()
  15. {
  16. staticOutput2();
  17. };
  18. };
  19. int main()
  20. {
  21. classA tempA;
  22. tempA.staticOutput();
  23. tempA.outPut2();
  24. cin.get();
  25. return 0;
  26. }

error C2352: “classA::outPut”: 非静态成员函数的非法调用 
结论4:非static成员函数可以引用static成员函数,但static成员函数不能引用非static成员函数

通过以上的例子,可以总结如下:

static变量

  1. 枚举在类声明时初始化;static const可在类声明中初始化,也可在类外面初始化;const和引用在构造函数初始化列表中初始化;static成员变量只能在类外面初始化
  2. static成员必须先初始化再使用,在类的方法中初始化或者在main()开始之前、类的声明之后的特殊地带为它提供定义和初始化
  3. 公有static成员变量可以通过类名或者类对象调用,方式为“类名+::”或者“对象名+.”或“对象指针+->”;公有继承类的调用方式与基类相同
  4. 私有static成员不能被类外部函数访问,也不能被对象访问,对于继承类也是如此

static函数

  1. 公有static成员函数可以通过类名或者类对象调用,方式为“类名+::”或者“对象名+.”或“对象指针+->”;公有继承类的调用方式与基类相同。而私有static成员函数不能通过类或对象调用
  2. static成员函数可以引用static成员变量,但不能引用非static成员
  3. 非static成员函数可以引用static成员
  4. 非static成员函数可以引用static成员函数,但static成员函数不能引用非static成员函数
  5. 不能通过类名来调用类的非静态成员函数

* 欢迎关注本人博客 *

0 0