练习15.23
假设第550页的D1类需要覆盖它继承而来的fcn函数,你应该如何对其进行修改?如果你修改之后fcn匹配了Base中的定义,则该节的那些调用语句将如何解析?
解答:
class D1 :public Base{
public:
int fcn(){
cout << "D1 fcn()" << endl;
return 1;
}
int fcn(int a){
cout << "D1 fcn(int)" << endl;
return 0;
}
virtual void f2(){
cout << "D1 f2" << endl;
}
};
对于第二问的理解,我认为应该是在D1中重载fcn()后,依旧想要调用Base中的fcn()
class D1 :public Base{
public:
using Base::fcn;
int fcn(){
cout << "D1 fcn()" << endl;
return 1;
}
int fcn(int a){
cout << "D1 fcn(int)" << endl;
return 0;
}
virtual void f2(){
cout << "D1 f2" << endl;
}
};
这里使用using声明语句指定一个名字,这样派生类中使用到的就是这个基类的函数定义了,即使重载了这个函数,使用的依旧是基类中的定义。
练习15.24
哪种类需要虚析构函数?虚析构函数必须执行什么样的操作?
解答:
【引用百度百科】
虚析构函数是为了解决基类的指针指向派生类对象,并用基类的指针删除派生类对象。
如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。因为它会为类增加一个虚函数表,使得对象的体积翻倍,还有可能降低其可移植性。
所以基本的一条是:无故的声明虚析构函数和永远不去声明一样是错误的。实际上,很多人这样总结:当且仅当类里包含至少一个虚函数的时候才去声明虚析构函数。
抽象类是准备被用做基类的,基类必须要有一个虚析构函数,纯虚函数会产生抽象类,所以方法很简单:在想要成为抽象类的类里声明一个纯虚析构函数。
虚析构函数能够确保delete基类指针时将运行正确的析构函数版本。