1. 问题引入
实现功能程序,统计某个类在程序执行期间生成对象的总数:
int global_cnt = 0;
class cls
{
public:
int a;
cls();
~cls();
};
cls::cls()
{
++global_cnt;
}
cls::~cls()
{
--global_cnt;
}
int main(void)
{
std::cout << "当前cls对象个数: " << global_cnt << std::endl;
cls c1;
cls c2;
std::cout << "当前cls对象有个数: " << global_cnt << std::endl;
return 0;
}
这是通过静态全局变量来实现的,在构造函数中自加global_cnt变量,在析构函数自减global_cnt。global_cnt变量位于全局数据区,它不属于具体某个对象。程序功能正确运行。
若不使用全局变量,还能怎么办?用类的静态成员变量。
2. 静态成员变量
回顾类的普通成员变量,具有的特点是:
(1) 外部可以通过对象名访问public成员变量;
(2) 成员变量是对象所专属的;
(3) 成员变量不能在对象之间共享。
对于类的静态成员变量来说,
(1) 它位于全局数据区,不依赖、也不属于任何对象,而是归属于整个类所有;
(2) 通过类名、也可以通过对象名,访问公有的静态成员变量;
(3) 所有对象共享静态成员变量。
使用静态成员变量也十分简单,
(1) 在定义成员变量时直接通过static关键字修饰
class cls
{
public:
static int a; //静态成员变量
}
(2) 注意,静态成员变量需要在类的外部分配空间(定义)
int cls::a = 6;
采用静态成员变量的程序为:
class cls
{
public:
int a;
static int cnt;
cls();
~cls();
int get_cnt()
{
return cnt;
}
};
int cls::cnt = 0;
cls::cls()
{
++cnt;
}
cls::~cls()
{
--cnt;
}
int main(void)
{
cls c1;
std::cout << "当前cls对象个数为: " << c1.get_cnt() << std::endl;
cls c2;
std::cout << "当前cls对象个数为: " << c1.get_cnt() << std::endl;
return 0;
}
输出结果如下:
3. 静态成员函数
如上代码,要得到cnt的值,就需要定以一个对象,通过对象去调用类的普通方法get_cnt()。假设我们想实现类似静态成员变量的功能,在没有定义类的前提下也可以获取cnt数值,有什么办法?那就要用静态成员函数了。
跟类的静态成员变量类似,静态成员函数:
(1) 归属于整个类所有;
(2) 既可以通过类名,也可以通过函数名访问静态成员变量;
(3) 不含有this指针,具体原因在前面this指针文章有说到,http://blog.csdn.net/qq_29344757/article/details/76427588;
(4) 不能访问类中的普通成员变量和普通成员函数,即只能访问类中的静态成员变量和静态成员函数。为什么?
对于普通成员方法:
class cls
{
public:
static a;
void SetVal(int i)
{
a = i;
}
}
SetVal()方法的实现其实质是:
void SetVal(int i)
{
this->a = i;
}
所有类的对象都共享位于代码段的成员函数,普通成员变量位于某个对象的堆栈空间,即普通成员变量在对象间不共享。方法通过this指针区分对象各自的堆栈的成员变量,静态成员函数不含有this指针,无法区分,也就无法访问普通成员变量咯。
在定义成员函数时直接通过static关键字修饰:
class cls
{
public:
static int func();
static int func_t()
{
//...
}
}
int func()
{
//...
}
所以要实现没有定义类的前提下也可以成员函数获取cnt数值,只需要将get_cnt()赋予静态函数的属性即可:
class cls
{
public:
int a;
static int cnt;
cls();
~cls();
static int get_cnt()
{
return cnt;
}
};
int cls::cnt = 0;
cls::cls()
{
++cnt;
}
cls::~cls()
{
--cnt;
}
int main(void)
{
std::cout << "当前cls对象个数为: " << cls::get_cnt() << std::endl;
cls c1;
cls c2;
std::cout << "当前cls对象个数为: " << cls::get_cnt() << std::endl;
cls *c3 = new cls;
std::cout << "当前cls对象个数为: " << c1.get_cnt() << std::endl;
delete c3;
std::cout << "当前cls对象个数为: " << c1.get_cnt() << std::endl;
return 0;
}
运行结果: