一般情况下类的析构函数里面都是释放内存资源,而析构函数不被调用的话就会造成内存泄漏
下面是基类没有使用虚析构的例子,如果派生类中的析构函数中进行内存释放,就会导致内存泄露:
#include <iostream>
using namespace std;
class ClxBase
{
public:
ClxBase() {cout << "i am ClxBase! create" << endl;};
~ClxBase() {cout << "i am ClxBase! destroy" << endl;};
virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};
class ClxDerived : public ClxBase
{
public:
ClxDerived() {cout << "i am ClxDerived! create" << endl;};
~ClxDerived() { cout << "i am ClxDerived! destroy" << endl; };
void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};
/*
纯虚函数必须被重写
虚函数可以被重写
这样当基类指针指向子类对象时候,调用函数时候即就是调用子类的函数的
*/
int main()
{
ClxBase *pTest = new ClxDerived;
pTest->DoSomething();
delete pTest;
return 0;
}
i am ClxBase! create
i am ClxDerived! create
Do something in class ClxDerived!
i am ClxBase! destroy//为何派生类的析构未调用呢?
注意:基类--子类均有DoSomething(),且是一般的函数则
class ClxDerived : public ClxBase
ClxBase *pTest = new ClxDerived;
pTest->DoSomething();调用基类的函数
delete pTest ;释放派生类对象:先执行派生类的析构再执行基类的析构
但是上面输出结果为什么?
派生类对象的地址可以赋给指向基类对象的指针变量,也就是说,指向基类对象的指针变量也可以指向派生类对象。总结<--通过指向基类对象的指针,只能访问派生类中的基类成员,而不能访问派生类增加的成员-->
人们有时希望通过使用基类指针能够调用基类和子类对象的成员, 但在应用上却不能完全满足人们的希望。
现知道基类对象的指针变量指向了派生类对象,那如何通过基类指针变量调用派生类对象的函数?
答:只需要让基类为虚函数, 子类重写该函数就行了,这样通过指向基类对象的指针指向派生类变量,再通过基类指针访问派生类函数就行 。
=======================================================
解决办法:基类中改为虚析构
#include <iostream>
using namespace std;
class ClxBase
{
public:
ClxBase() {cout << "i am ClxBase! create" << endl;};
virtual ~ClxBase() {cout << "i am ClxBase! destroy" << endl;};
virtual void DoSomething() { cout << "Do something in class ClxBase!" << endl; };
};
class ClxDerived : public ClxBase
{
public:
ClxDerived() {cout << "i am ClxDerived! create" << endl;};
~ClxDerived() { cout << "i am ClxDerived! destroy" << endl; };
void DoSomething() { cout << "Do something in class ClxDerived!" << endl; };
};
int main()
{
ClxBase *pTest = new ClxDerived;
pTest->DoSomething();
delete pTest;
return 0;
}
输出如下:
i am ClxBase! create
i am ClxDerived! create
Do something in class ClxDerived!
i am ClxDerived! destroy
i am ClxBase! destroy
1. 如果一个类有虚函数功能,它经常作为一个基类使用。
2.如果它是一个基类,它的派生类经常使用new来分配。
3.如果一个派生类对象使用new来分配,并且通过一个指向它的基类的指针来控制,那么它经常通过一个指向它的基类的指针来删除它(如果基类没有虚析构函数,结果将是不确定的,实际发生时,派生类的析构函数永远不会被调用)。