C++中的基类析构函数需要定义成虚方法
通过new子类对象赋值给基类对象时:
代码1:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:
Base() { a = new char; cout << "base construct" << endl; };
~Base() { delete a; cout << "base destroy" << endl; };
void doSomething() { cout <<"base dosomething" <<endl; };
private:
char* a;
};
class Derived:public Base
{
public:
Derived() { a = new char; cout << "derived construct" << endl; };
~Derived() { delete a; cout << "derived destroy" << endl; };
void doSomething() { cout << "derived dosomething" << endl; };
private:
char* a;
};
int main()
{
Base *p = new Derived;
p->doSomething();
delete p;
getchar();
return 1;
}
输出是:
base construct
derived construct
base dosomething
base destroy
说明:p是Base的对象,所以通过p调用的一定是Base类的成员方法。基类是正常构造和析构的,但是子类只是进行了构造没有进行析构,造成子类中new出的a的指针对象是没有被delete,因此造成内存的泄漏。通过申明基类的析构方法为virtual,基类中虚函数表中记录了其析构函数是虚函数,而子类也有对应的实现方法,从而会先调用子类的析构函数再调用基类的析构。 下面是修改后的代码:
class Base
{
public:
Base() { a = new char; cout << "base construct" << endl; };
virtual ~Base() { delete a; cout << "base destroy" << endl; };
void doSomething() { cout <<"base dosomething" <<endl; };
private:
char* a;
};
输出是:
base construct
derived construct
base dosomething
derived destroy
base destroy
通过new基类对象赋值给子类对象时:
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:
Base() { a = new char; cout << "base construct" << endl; };
virtual ~Base() { delete a; cout << "base destroy" << endl; };
void doSomething() { cout <<"base dosomething" <<endl; };
private:
char* a;
};
class Derived:public Base
{
public:
Derived() { a = new char; cout << "derived construct" << endl; };
~Derived() { delete a; cout << "derived destroy" << endl; };
void doSomething() { cout << "derived dosomething" << endl; };
private:
char* a;
};
int main()
{
Derived *p = (Derived* )new Base;
p->doSomething();
delete p;
getchar();
return 1;
}
输出是:
base construct
derived dosomething
base destroy
没有进入子类的构造函数,如果子类方法中访问了子类的成员时会出现不可控的现象。所以通过new子类的对象赋值给基类指针是不建议的用法。