经历过某同一家公司的两次面试, 都被问到了基类虚析构函数问题, 其实, 很简单很基础。 下面我们来看程序:
#include <iostream>
using namespace std;
class A
{
public:
~A()
{
cout << "~A" << endl;
}
};
class B : public A
{
public:
~B()
{
cout << "~B" << endl;
}
};
int main()
{
A *p = new B;
return 0;
}
结果A,B的析构函数都不会被调用到。 继续看:
#include <iostream>
using namespace std;
class A
{
public:
~A()
{
cout << "~A" << endl;
}
};
class B : public A
{
public:
~B()
{
cout << "~B" << endl;
}
};
int main()
{
A *p = new B;
delete p;
return 0;
}
结果为:~A
好, 继续看:
#include <iostream>
using namespace std;
class A
{
public:
virtual ~A()
{
cout << "~A" << endl;
}
};
class B : public A
{
public:
~B()
{
cout << "~B" << endl;
}
};
int main()
{
A *p = new B;
delete p;
return 0;
}
结果为:
~B
~A
可见, 应该为多态基类声明virtual析构函数, 否则调用不到派生类的析构函数, 容易造成资源泄露。
当然, 并不是所有基类的存在都是为了派生、多态的, 比如STL的string类, 所以标准string是不含virtual函数的。 那怎么验证string的析构函数不是virtual函数呢? 很简单, 且看:
#include <iostream>
#include <string>
using namespace std;
class Test : public string
{
public:
~Test()
{
cout << "~Test" << endl;
}
};
int main()
{
string *p = new Test;
delete p;
return 0;
}
从结果看, 没有调用到Test的析构函数。 其实呢, 让一个类去继承string, 这是个很馊很馊的主意。
OK, 本文先介绍到这里。