静态成员简述
在C++中,静态成员是属于整个类的而不是某个对象,静态成员变量只存储一份供所有对象共用。所以在所有对象中都可以共享它。使用静态成员变量实现多个对象之间的数据共享不会破坏隐藏的原则,保证了安全性还可以节省内存。
静态成员的定义或声明要加个关键static。静态成员可以通过双冒号来使用即<类名>::<静态成员名>。
第一个例子,通过类名调用静态成员函数和非静态成员函数
class Point
{
public:
void init()
{
}
static void output()
{
}
};
void main()
{
Point::init();
Point::output();
}
出现编译错误:error C2352: 'Point::init' : illegal call of non-static member function
结论1:不能通过类名来调用类的非静态成员函数。
第二个例子,通过类的对象调用静态成员函数和非静态成员函数
以上代码可改为:
void main()
{
Point pt;
pt.init();
pt.output();
}
** 结论2:类的对象可以使用静态成员函数和非静态成员函数。**
第三个例子,在类的静态成员函数中使用类的非静态成员
#include <stdio.h>
class Point
{
public:
void init()
{
}
static void output()
{
printf("%d\n", m_x);
}
private:
int m_x;
};
void main()
{
Point pt;
pt.output();
}
编译出错:error C2597: illegal reference to data member 'Point::m_x' in a static member function
因为静态成员函数属于整个类,在类实例化对象之前就已经分配空间了,而类的非静态成员必须在类实例化对象后才有内存空间,所以这个调用就出错了,就好比没有声明一个变量却提前使用它一样。
结论3:静态成员函数中不能引用非静态成员。
第四个例子,在类的非静态成员函数中使用类的静态成员
class Point
{
public:
void init()
{
output();
}
static void output()
{
}
};
void main()
{
Point pt;
pt.output();
}
编译通过。
结论4:类的非静态成员函数可以调用用静态成员函数,但反之不能。
第五个例子,使用类的静态成员变量
1. #include <stdio.h>
2. class Point
3. {
4. public:
5. Point()
6. {
7. m_nPointCount++;
8. }
9. ~Point()
10. {
11. m_nPointCount--;
12. }
13. static void output()
14. {
15. printf("%d\n", m_nPointCount);
16. }
17. private:
18. static int m_nPointCount;
19. };
20. void main()
21. {
22. Point pt;
23. pt.output();
24. }
按Ctrl+F7编译无错误,按F7生成EXE程序时报链接错误
error LNK2001: unresolved external symbol "private: static int Point::m_nPointCount" (?m_nPointCount@Point@@0HA)
这是因为类的静态成员变量在使用前必须先初始化。
在main()函数前加上int Point::m_nPointCount = 0;
再编译链接无错误,运行程序将输出1。
结论5:类的静态成员变量必须先初始化再使用。
小结
1.静态成员函数中不能调用非静态成员。
2.非静态成员函数中可以调用静态成员。因为静态成员属于类本身,在类的对象产生之前就已经存在了,所以在非静态成员函数中是可以调用静态成员的。
3.静态成员变量使用前必须先初始化,否则会在linker时出错。
以上大部分是从网上摘来的(链接)
,本人敲的代码如下:
#include <bits/stdc++.h>
using namespace std;
class Apple {
public:
Apple(){
nTotalNumber++;
}
~Apple(){
nTotalNumber--;
}
static int nTotalNumber;
static void PrintTotal() {
cout << nTotalNumber << endl;
}
};
int Apple::nTotalNumber = 0;
Apple Fun(const Apple & a) {
a.PrintTotal();
return a;
}
int main()
{
Apple * p = new Apple[4];
Fun(p[2]);
Apple p1,p2;
Apple::PrintTotal ();
delete [] p;
p1.PrintTotal ();
return 0;
}
Apple()是构造函数,每创建一个对象就会执行一次,并在离开作用域之前一直存在;
~Apple()是析构函数,在离开作用域后就会执行(数组p在delete后就会执行析构函数)。
PS:明天军训第一天,祝自己好运。
网友评论