通过前面的学习,我们已经在面向对象编程技术的世界里大大的迈出了第一步。 我们掌握了继承,学会如何把需要解决的问题转换成一个类的层次结构,但我们在写代码的过程中还是遇到很多问题无法解决,所以我们需要进一步的学习。 接下来,我们会介绍一系列 C++ 和面对对象编程技术中的一些比较高级的概念:静态对象和静态方法,虚方法,抽象方法和多态等。
面对对象编程技术的一个重要特征是用一个对象把数据和对数据处理的方法封装在一起。 大家还记得,在前边的例子里我们一直是在使用对象(也可以说某个类的实例)来调用方法,每个方法只处理调用它的那个对象所包含的数据,所有的数据都属于同一个对象。 这就引发了一个问题:如果我们所需要的功能或数据不属于某个特性的对象,而是属于整个类的,该怎么办?
我们不妨假设现在需要统计一下有多少只活的动物。那么我们需要有一个计数器变量:每诞生一只宠物,就给宠物计数器加上1; 每挂掉一只,就j减去1。 我们首先想到的是创建一个全局变量来充当这个计数器,但这么做的后果是程序中的任何代码都可以修改这个计数器,稍不小心就会在程序里留下一个难以查堵的漏洞。 所以坚决不建议在非必要的时候声明全局变量。
我们真正需要的是一个只在创建或删除对象时候才允许访问的计数器。 这个问题必须使用 C++ 的静态属性和静态函数才能完美地得到解决。 C++ 允许我们把一个或多个成员声明为属于某个类,而不是仅属于该类的对象。(就是说这个成员仅能让该类强暴) 这么做的好处是程序员可以在没有创建任何对象的情况下调用有关的方法。
另外一个好处是能够让有关的数据仍在该类的所有对象间共享。 创建一个静态属性和静态方法: 只需要在它的声明前加上 static 保留字即可。 关于 static 的巩固学习:bbs.fishc.com 好吧,大家都晕晕了吧?还是让例子来解释上边的纯理论:example.cpp
#include#include class Pet{public: Pet(std::string theName); ~Pet(); static int getCount();protected: std::string name;private: static int count;};class Dog : public Pet{public: Dog(std::string theName);};class Cat : public Pet{public: Cat(std::string theName);};int Pet::count = 0; // 注意这一句:他起码做了两件事:为count分配内存且在静态存储区初始化为0 Pet::Pet(std::string theName){ name = theName; count++; std::cout << "一只宠物出生了,名字叫做: " << name << "\n";}Pet::~Pet(){ count--; std::cout << name << "挂掉了\n";}int Pet::getCount(){ return count;}Dog::Dog(std::string theName) : Pet(theName){}Cat::Cat(std::string theName) : Pet(theName){}int main(){ Dog dog("Tom"); Cat cat("Jerry"); std::cout << "\n已经诞生了" << Pet::getCount() << "只宠物!\n\n"; { //声明一个区域,即作用范围,去掉运行结果会不同,一定要运行看看 Dog dog_2("Tom_2"); Cat cat_2("Jerry_2"); std::cout << "\n现在呢,已经诞生了" << Pet::getCount() << "只宠物!\n\n"; } std::cout << "\n现在还剩下 " << Pet::getCount() << " 只宠物!\n\n"; return 0;}