当一个基类被设计为多态用途,可能被多个类继承时,有一个很容易被忽略但又可能造成灾难性错误的一点是:
基类的析构函数没有声明为virtual。
首先,我们不将基类的析构函数声明为virtual,看看结果怎样。代码验证如下:
-
#include <iostream>
-
#include <string.h>
-
-
class Base {
-
public:
-
Base()
-
{
-
std::cout << "Base..." << std::endl;
-
}
-
-
~Base()
-
{
-
std::cout << "~Base..." << std::endl;
-
}
-
};
-
-
class A: public Base {
-
public:
-
A()
-
{
-
std::cout << "A..." << std::endl;
-
name = new char(64);
-
strcpy(name, "virtual-destructor");
-
std::cout << "name: " << name << std::endl;
-
}
-
-
~A()
-
{
-
std::cout << "~A..." << std::endl;
-
delete name;
-
name = NULL;
-
}
-
-
private:
-
char *name;
-
};
-
-
int main()
-
{
-
Base *pb;
-
A *pa;
-
-
pa = new A();
-
delete pa;
-
std::cout << ".........................................." << std::endl;
-
pb = new A();
-
delete pb;
-
-
return 0;
-
}
结果输出:
Base...
A...
name: virtual-destructor
~A...
~Base...
..........................................
Base...
A...
name: virtual-destructor
~Base...
从输出的结果可以看到,基类指针pb指向类A新创建的对象,在释放pb时,其实只释放了基类对象的资源,而继承类A相关的资源并未被释放,这样造成了资源泄漏!
倘若我们将基类的析构函数声明为virtual,看看测试结果有何变化。
-
#include <iostream>
-
#include <string.h>
-
-
class Base {
-
public:
-
Base()
-
{
-
std::cout << "Base..." << std::endl;
-
}
-
-
virtual ~Base()
-
{
-
std::cout << "~Base..." << std::endl;
-
}
-
};
-
-
class A: public Base {
-
public:
-
A()
-
{
-
std::cout << "A..." << std::endl;
-
name = new char(64);
-
strcpy(name, "virtual-destructor");
-
std::cout << "name: " << name << std::endl;
-
}
-
-
~A()
-
{
-
std::cout << "~A..." << std::endl;
-
delete name;
-
name = NULL;
-
}
-
-
private:
-
char *name;
-
};
-
-
int main()
-
{
-
Base *pb;
-
A *pa;
-
-
pa = new A();
-
delete pa;
-
std::cout << ".........................................." << std::endl;
-
pb = new A();
-
delete pb;
-
-
return 0;
-
}
结果输出:
Base...
A...
name: virtual-destructor
~A...
~Base...
..........................................
Base...
A...
name: virtual-destructor
~A...
~Base...
可以看到,当基类的析构函数被声明为virtual后,尽管pb的类型是Base *,但delete pb的时候,安全地将所有的资源释放掉了。
当然,如果一个类不是被设计带有多态性的基类,比如标准string和STL容器,那么就不该为其声明virtual析构函数。
阅读(1170) | 评论(0) | 转发(0) |