在C++中,static成员属于整个类而不是某个对象。不管类创建了多少对象,static成员只存储一份供所有对象使用。
在使用static成员时,对于它的声明、初始化和使用经常感到困惑,在此结合例子说明,希望能加深读者对于static成员的理解。
类中static成员有两种,一是static成员变量,一种是static成员函数。首先,先分析一下static成员变量。
第一个例子:static、static const、const和枚举的初始化
class classA{const int ciNum;enum{eNum=10}; //枚举在类声明时初始化int arr[eNum];public:classA():ciNum(10){} //const变量只能在构造函数初始化列表中初始化static int siNum;static const int sciNum=10; //static const可在类声明时初始化static const int sciNumOut;};int classA::siNum=10; //static变量必须在类外面初始化,但不需要加static修饰符const int classA::sciNumOut=10; //static const可在类外面初始化,不加static,但要加cosntint main(){cout<<classA::siNum<<endl;cout<<classA::sciNum<<endl;cout<<classA::sciNumOut<<endl;return 0;}
编译通过
结论1:枚举在类声明时初始化;static const可在类声明中初始化,也可在类外面初始化;const和引用在构造函数初始化列表中初始化;static成员变量只能在类外面初始化
第二个例子:static成员变量的引用
class classA{public:static int pub_siNum;};class classB: public classA{};int classA::pub_siNum=10;int main(){classA tempA;classB tempB;cout<<classA::pub_siNum<<endl;cout<<tempA.pub_siNum<<endl;cout<<classB::pub_siNum<<endl;cout<<tempB.pub_siNum<<endl;return 0;}
编译通过
结论2:公有static成员变量可以通过类名或者类对象调用,方式为“类名+::”或者“对象名+.”或“对象指针+->”;公有继承类的调用方式与基类相同
class classA{static int pri_siNum;};class classB: public classA{};int classA::pri_siNum=10; //初始化方式同公有static成员变量int main(){classA tempA;classB tempB;cout<<classA::pri_siNum<<endl;cout<<tempA.pri_siNum<<endl;cout<<classB::pri_siNum<<endl;cout<<tempB.pri_siNum<<endl;return 0;}
编译出错:error C2248: “classA::pri_siNum”: 无法访问 private 成员(在“classA”类中声明)
结论3:私有static成员不能被类外部函数访问,也不能被对象访问,对于继承类也是如此
接下来分析一下static成员函数:
第一个例子:static成员函数的引用
class classA{public:static void init(){}};class classB: public classA{};int main(){classA tempA;classB tempB;classA::init();tempA.init();classB::init();tempB.init();return 0;}
编译通过
结论1:公有static成员函数可以通过类名或者类对象调用,方式为“类名+::”或者“对象名+.”或“对象指针+->”;公有继承类的调用方式与基类相同。而私有static成员函数不能通过类或对象调用
第二个例子,在类的static成员函数中使用类的非static成员
class classA{public:int iNum;static void output(){cout << ++siNum;cout << iNum;}private:static int siNum;};int classA::siNum=10;int main(){classA tempA;tempA.iNum=10;tempA.output();return 0;}
编译出错:error C2597: 对非静态成员“classA::iNum”的非法引用
因为static成员函数属于整个类,在类实例化对象之前就已经分配空间了,而类的非static成员必须在类实例化对象后才有内存空间,所以这个调用就出错了,就好比没有声明一个变量却提前使用它一样。
结论2:static成员函数可以引用static成员变量,但不能引用非static成员
第三个例子,在类的非static成员函数中使用类的static成员
class classA{public:int iNum;void output(){cout << ++siNum;cout << iNum;}private:static int siNum;};int classA::siNum=10;int main(){classA tempA;tempA.iNum=10;tempA.output();return 0;}
编译通过
结论3:类的非static成员函数可以引用static成员
第四个例子:static成员函数和非static成员函数的相互引用
class classA{public:void outPut(){};static void staticOutput(){outPut();};static void staticOutput2(){};void outPut2(){staticOutput2();};};int main(){classA tempA;tempA.staticOutput();tempA.outPut2();cin.get();return 0;}
error C2352: “classA::outPut”: 非静态成员函数的非法调用
结论4:非static成员函数可以引用static成员函数,但static成员函数不能引用非static成员函数
通过以上的例子,可以总结如下:
static变量
- 枚举在类声明时初始化;static const可在类声明中初始化,也可在类外面初始化;const和引用在构造函数初始化列表中初始化;static成员变量只能在类外面初始化
- static成员必须先初始化再使用,在类的方法中初始化或者在main()开始之前、类的声明之后的特殊地带为它提供定义和初始化
- 公有static成员变量可以通过类名或者类对象调用,方式为“类名+::”或者“对象名+.”或“对象指针+->”;公有继承类的调用方式与基类相同
- 私有static成员不能被类外部函数访问,也不能被对象访问,对于继承类也是如此
static函数
- 公有static成员函数可以通过类名或者类对象调用,方式为“类名+::”或者“对象名+.”或“对象指针+->”;公有继承类的调用方式与基类相同。而私有static成员函数不能通过类或对象调用
- static成员函数可以引用static成员变量,但不能引用非static成员
- 非static成员函数可以引用static成员
- 非static成员函数可以引用static成员函数,但static成员函数不能引用非static成员函数
- 不能通过类名来调用类的非静态成员函数
* 欢迎关注本人博客 *
本文详细解析了C++中static成员的概念、初始化、引用方式及使用注意事项,包括static变量和static函数的区别与特性,通过具体例子帮助读者深入理解并正确运用static成员。
534

被折叠的 条评论
为什么被折叠?



