#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销毁对象时,只调用了基类的析构函数,未调用派生类的析构函数。这样会造成销毁对象不完全。
- 静态成员变量要提前初始化