虚函数:
1.带virtual关键字;
2.父类有定义,并且有功能,子类继承后可以重写这个功能(在Qt中经常见到 父类::此函数(参数)进行父类的调用,这样做是为了把父类的逻辑"继承"下来);
纯虚函数:
1.带virtual关键字;
2.函数尾巴后面带=0;
3.在C++中一般充当接口的功能;
虚析构函数:
1.带virtual关键字;
2.目的是为了把内存释放干净(造成这样的原因是因为父类指向子类对象,delete父类后,子类不会析构(除非父类是虚析构函数,不然不会被释放))
下面来一个栗子:
代码如下:
#include <iostream>
#include <conio.h>
#include <string>
using namespace std;
class API {
public:
virtual string createAWorld() = 0;
virtual void alterWorldName(string name) = 0;
~API() { //No virtual function
cout << "Destroy API called\n";
}
protected:
API() {
cout << "API construction called!\n";
}
};
class Implementation :public API {
public:
string createAWorld() {
cout << "ImplementationOne createAWorld called!\n";
m_name = "earth";
return "successful";
}
void alterWorldName(string name) {
m_name = name;
}
~Implementation() {
cout << "Destroy Implementation called\n";
}
private:
string m_name;
};
class Base {
public:
virtual void printClassName() {
cout << "The class is Base\n";
}
Base() {
cout << "Base construction called\n";
}
virtual ~Base() {
cout << "Virtual destroy Base Called\n";
}
};
class Child :public Base {
public:
void printClassName() {
cout << "The class is Child\n";
cout << "farther's pinrtClassName():";
Base::printClassName();
}
Child() {
cout << "Child construction called\n";
}
~Child() {
cout << "Destroy Child Called\n";
}
};
void main() {
Implementation *imp = new Implementation;
imp->createAWorld();
cout << "\n";
Child *child = new Child;
child->printClassName();
delete child;
delete imp;
cout << "\n";
Child *pChild = new Child;
Base *base = pChild;
base->printClassName();
delete base;
cout << "\n";
API *api = new Implementation;
api->createAWorld();
delete api;
_getch();
}
程序运行截图如下:
一共有4个部分:
这里就说明下最后2个部分,
倒数第二个部分:
Base里面有个虚析构函数,所有虽然他被delete掉了,但他会先去调用子类的虚构函数。
倒数第一个部分:
API这个类里面的析构函数不是虚析构函数,所以他没有调用子类的析构函数,这样就造成内存释放不干净!