C++中对C的扩展学习新增内容———面向对象(继承)纯虚函数和虚析构函数以及纯虚析构函数
纯虚函数和虚析构函数以及纯虚析构函数
纯虚函数(抽象类):
1、当一个类包含了纯虚函数,这个类就不能用来创建对象了。这个类叫做抽象类。
2、当一个类继承了父类的话,必须去重写父类的纯虚函数。如果子类不重写父类的纯虚函数,子类仍然是抽象类。
3、纯虚函数的实现:
class Animal { public: virtual void speak() = 0; // 纯虚函数 };
虚析构函数以及纯虚析构函数:
1、通过父类指针释放子类对象问题
class Animal { public: Animal() { cout << "Animal 构造函数" << endl; p_name = new char[100]; } virtual void speak() { cout << "Animal 说话..." << endl; } // virtual ~Animal() {} // virtual ~Animal() = default; //C++11 virtual ~Animal() { cout << "Animal 析构函数" << endl; if (p_name != nullptr) { delete[] p_name; p_name = nullptr; } } public: char *p_name; }; class Dog : public Animal { public: Dog() { cout << "Dog 构造函数" << endl; p_name2 = new char[100]; } virtual void speak() { cout << "Dog 说话..." << endl; } ~Dog() { cout << "Dog 析构函数" << endl; if (p_name2 != nullptr) { delete[] p_name2; p_name2 = nullptr; } } public: char *p_name2; }; void test01() { // 父类构造 子类构造 Animal *animal = new Dog; animal->speak(); // delete animal; // 当多态发生时,如果通过父类指针去释放子类对象,默认情况只会调用父类的析构函数。可能会导致内存泄漏。 }
当多态发生时如果通过父类指针去释放子类对象,默认情况只会调用父类的析构函数。可能会导致内存泄漏。
2、虚析构函数的作用(通过父类指针去释放子类对象)没如果要实现多态,最好父类中增加一个虚析构函数。
3、虚析构函数和纯虚析构函数
(1) 纯虚析构函数要在类外增加函数体。
(2) 如果类的内部写了纯虚析构函数,该类就是抽象类(不能被实例化)。
(3) 一般情况下,写虚析构函数即可,类的内部有很多带有实现的虚函数,此时又希望该类为抽象类,此时我们可以将析构函数设置为纯虚析构函数,使得该类变成抽象类。
class Animal { public: Animal() { cout << "Animal 构造函数" << endl; p_name = new char[100]; } virtual void speak() { cout << "Animal 说话..." << endl; } virtual ~Animal() = 0; // 纯虚析构函数 public: char *p_name; }; Animal::~Animal() { } class Dog : public Animal { public: Dog() { cout << "Dog 构造函数" << endl; p_name2 = new char[100]; } virtual void speak() { cout << "Dog 说话..." << endl; } ~Dog() { cout << "Dog 析构函数" << endl; if (p_name2 != nullptr) { delete[] p_name2; p_name2 = nullptr; } } public: char *p_name2; }; void test02() { Animal *animal = new Dog; animal->speak(); delete animal; }