虚析构函数
如果一个类将定义成基类,则其析构函数要定义为虚析构函数, 不然可能引起派生类的内存泄漏, 例如:
class A
{
private:
int *a;
public:
A()
{
a = new int[4];
}
~A()
{
delete [] a;
}
};
class B:public A
{
private:
int *b;
public:
B():A()
{
b = new int[4];
}
~B()
{
delete [] b;
}
};
void main()
{
A* ptr = new B;
delete ptr; // 在这里只调用了基类A的析构函数, 将B中从A继承过来时为基类成员变量int *a分配的内存释放了.
// 但是因为没有调用派生类B的析构函数,所以B的成员变量int *b分配到的内存没有释放掉.
}
如果基类定义成如下形式:
class A
{
private:
int *a;
public:
A()
{
a = new int[4];
}
virtual ~A()
{
delete [] a;
}
};
将基类析构函数定义成virtual 则在执行delete ptr时会先调用指针ptr指向对象本身的析构函数,再调用基类的析构函数.
纯虚函数
class A
{
public:
virtual void f() = 0;
};
f() 是纯虚函数, 纯虚函数只需要声明, 不需要定义. 有一个或者几个纯虚函数的类, 称为抽象类. 抽象类作为基类, 为派生类提供一组操作界面,不能对抽象类进行定义. 例如:
A k; // 这是不可取的,因为A是一个抽象类.
抽象类作为基类被派生时, 它的所有纯虚函数在派生类中都要有所定义, 否则, 派生类也为抽象类.
疑问:
1, 为什么应该尽量避免类型域?
2, 类型域到底有什么作用?
3,虚函数表是程序运行时只产生一个,还是各个带有虚函数的类都有一份属于自己的虚函数表?
4,虚函数机制的重要性, 如何体现?