面对对象编程技术的一个重要特征是用一个对象把数据和对数据处理的方法封装在一起。
大家还记得,在前面的例子里我们一直是在使用对象(也可以说是某个类的实例)来调用方法,每个方法只处理调用它的那个对象所包含的数据,所有的数据都属于同一个对象。
这就引发了一个问题:如果我们所需要的功能或者数据不属于某个特定的对象,而是属于整个类的,该怎么办?
我们不妨假设现在需要统计一下有多少只活的动物,那么我们需要一个计数器数量:每诞生一只宠物,就给宠物计数器加上1;每死掉一只,就减去1。
我们首先想到的是创建一个全局变量来充当这个计数器,但这么做的后果是程序中的任何代码都可以修改这个计数器,稍不小心就会在程序里留下一个难以查堵的漏洞。
所以坚决不建议在非必要的时候声明全局变量。
我们真正需要的是一个只有在创建或删除对象时候才允许访问的计数器。
这个问题必须使用C++的静态属性和静态函数才能完美地得到解决。
C++允许我们把一个或多个成员声明为属于每个类,而不是仅属于该类的对象。
这么做的好处是程序员可以在没有创建任何对象的情况下调用有关的方法。
另外一个好处是能够让有关的数据仍在该类的所有对象间共享。
创建一个静态属性和静态方法:
- 只需要在它的声明钱加上static保留字即可。
- 关于static的巩固学习见:C/C++中Static的作用详述
例子:
#include <iostream>
#include <string>
class Pet
{
public:
Pet(std::string theName);
~Pet();
static int getCount();
//static int count;
protected:
std::string name;
private:
static int count;
};
class Cat : public Pet
{
public:
Cat(std::string theName);
};
class Mouse : public Pet
{
public:
Mouse(std::string theName);
};
Pet::Pet(std::string theName)
{
count++;
name = theName;
std::cout << "这个新的宠物的名字叫做:" << name << std::endl;
}
Pet::~Pet()
{
count--;
std::cout << "这个新的宠物挂掉了" << std::endl;
}
int Pet::count = 0;
int Pet::getCount()
{
return count;
}
Cat::Cat(std::string theName) : Pet(theName)
{
}
Mouse::Mouse(std::string theName) : Pet(theName)
{
}
int main()
{
Cat cat("Tom");
Mouse mouse("Jerry");
std::cout << "\n已经诞生了" << Pet::getCount() << "只小宠物" << std::endl;
//std::cout << "\n已经诞生了" << Pet::count << "只宠物!\n\n";
{
Cat cat_2("Tom_2");
Mouse mouse_2("Jerry");
std::cout << "\n现在呢,已经诞生了" << Pet::getCount() << "只小宠物" << std::endl;
}
std::cout << "\n现在还剩下" << Pet::getCount() << "多少只宠物" << std::endl;
return 0;
}
这个里的这个接口函数返回的就是count这个属性的值,这样的话外面的语句就不能修改count的值但是可以读取它的值,试了一下,那个注释掉的话就是试了一下会怎么样,果然不行。
上面代码的输出结果是
如果把那个cat_2那一行的大括号去掉的话输出结果就变成了
应该能明白的吧