class cs
{
public:
cs();
virtual ~cs();
private:
};
cs::cs()
{
}
cs::~cs()
{
cout << "cs:destrutor" << endl;
}
class cc :public cs
{
public:
int w, h;
cc();
~cc();
private:
};
cc::cc()
{
}
cc::~cc()
{
cout << "cc:destrutor" << endl;
}
int main() {
//cc* p1 = new cc();
cs* p2 = new cc();
//delete p1;
delete p2;
return 0;
}
首先知道父类把函数声明为虚函数,子类继承的函数不用virtual 在进行声明。其次子类对象的内存里多了个虚函数表,类似操作系统的二级地址,在调用需要多态实现的函数时,会查找此表,通过表找到子类重写的方法。因此,在delete p2的时候会调析构函数,由于p2是父类型的指针,但实际指向的是子类对象的地址。
class cs
{
public:
cs();
~cs();
private:
};
先看不加virtual关键字的输出结果
调用的是父类的析构函数,没有new的子类对象的析构函数。这是因为编译器只表面知道p2的类型是父类类型。
int main() {
//cc* p1 = new cc();
cc* p3 = new cc();
cs* p2 = p3;
//delete p1;
delete p2;
return 0;
}
再不加virtual的情况下,这两种方式等价。
就是真正的对象并没有别释放,就是造成内存泄漏的问题。(如果detele语句在析构函数的话)。
这时加上virtual关键字的话,
子类的析构函数就被调用,也就释放空间了。
加virtual的原因就是实现多态,根据虚表找到了父类析构函数,再转到子类的析构函数。
那么构造函数能不能加virtual关键字修饰呢?
假设能,那么父类就不能初始化对象了。
总结:构造函数一定不是虚函数,析构函数可以是虚函数。