class Base
{
public:
Base(){}
virtual void VirFun()
{
}
~Base(){}//实际上这里必须加virtual
private:
//Some attribute
};
class Sub : public Base
{
public:
Sub(){}
virtual void VirFun()
{
}
~Sub(){}
private:
//Some attribute
};
上面的例子是个简单的多态。
在我们应用的时候,我们经常会这么干:
Base * pBase = new Sub();//new了一个Sub对象,它实际上包含了Base 的子对象。
pBase->VirFun(); //很好,它会根据实际的类型调用Sub 的 VirFun()
delete pBase;//完蛋了,它调用了Base的析构。Sub的析构?这可不关我事,我可是Base类型的。
于是内存泄漏了。。。
给Base的析构函数加上virtual之后呢?
delete pBase;//很好,它继续多态调用实际类型对象的析构。
大家知道,子类的析构函数会自动调用父类的析构。
于是,啊哈,终于安全了。
至此,大家应该对题目的意思有了大概的了解了。
有没有发现,virtual 析构函数挺有意思的,它的子类析构函数名字和父类不同,一样会重写父类的析构函数。
为什么题目要强调“多态 基类”呢?
class Base
{
public:
Base(){}
void Fun()
{
}
virtual ~Base(){}
private:
//Some attribute
};
class Sub : public Base
{
public:
Sub(){}
void Fun()
{
}
~Sub(){}
private:
//Some attribute
};
这样的继承中,有没有必要给父类析构函数加virtual呢?
从语法意义上来说,是应该的,因为你像下面这样写的时候,语法是没有错误的:
Base * pBase = new Sub();//new了一个Sub对象,它实际上包含了Base 的子对象。
delete pBase;//很好啊,程序多安全啊。有什么问题吗?
在这样写的时候,你应该谴责自己。
pBase的所有行为都是Base中定义的,为什么要给它一个Sub的身体呢?
(为什么CSDN上很多男士都爱用美女作头像呢。。。)
所以,当你设计的类系不具备多态性的时候,请不要:
1.用父类的指针指向子类;
2.给父类的析构函数加上virtual(毕竟虚函数表也是不小的开销不是?)l。