
#include <iostream>#include <cstring>using namespace std;class Animal{public:static int number;Animal() { number += 1; }virtual ~Animal() { number -= 1; } // 这里一定要用virtual,不然无法执行派生的析构函数};class Dog : public Animal{public:static int number;Dog(){Animal();number += 1;}~Dog(){number -= 1;}};class Cat : public Animal{public:static int number;Cat(){Animal();number += 1;}~Cat(){number -= 1;}};void print(){cout << Animal::number << " animals in the zoo, " << Dog::number << " of them are dogs, " << Cat::number << " of them are cats" << endl;}int Animal::number = 0; // 静态成员要声明int Dog::number = 0;int Cat::number = 0;int main(){print();Dog d1, d2;Cat c1;print();Dog *d3 = new Dog(); // new的这种也不会调用复制构造函数,毕竟是新建一个对象// 不是根据另一个已有对象来创建这个对象Animal *c2 = new Cat; // 主要是这一句比较难搞Cat *c3 = new Cat;print();delete c3;delete c2;delete d3;print();}
- 为什么父类的析构函数不定义成虚函数,删除c2的时候就不会调用~Cat()了?而为什么即使把父类的析构函数定义成虚函数,调用子类的析构函数后仍然会调用父类的虚函数?

析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数。如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销毁派生类的动态对象,那么用delete销毁对象时,只调用了基类的析构函数,未调用派生类的析构函数。这样会造成销毁对象不完全。
- 静态成员变量要提前初始化
