15.11 为你的Quote类体系添加一个名为debug的函数,令其分别显示每个类的数据成员。
void Quote::debug()const
{
cout << "bookNo: " << bookNo << " price: " << price;
}
void Bulk_Quote::debug()const
{
cout << "min_pty: " << min_qty << " discount: " << discount;
}
15.12 有必要将一个成员函数同时声明成override和final吗?为什么?
有必要,在派生类中,将成员函数声明成override预防意外,而final可以防止成员函数被后续的覆盖。
15.13 给定下面的类,解释每个print函数的机理:
class base {
public:
string name() { return basename; }
virtual void print(ostream &os) { os << basename ; }
private:
string basename;
};
class derived :public base {
public:
void print(ostream &os) { print(os); os << " " << i ; }
private:
int i;
};
第一个print输出基类的数据成员,第二个print输出基类和派生类的数据成员。
第二个print有误,如果一个派生类虚函数需要调用它的基类版本,但是没有使用作用域运算符,则在运行时该调用将被解析为对派生类版本自身的调用,从而导致无限递归。
修改如下:
void print(ostream &os) { base::print(os); os << " " << i ; }
练习15.14 给定上一题中的类以及下面这些对象,说明在运行时调用哪个函数:
#include <iostream>
#include <string>
using namespace std;
class base {
public:
string name() { cout << "base name" << endl; return basename; }
virtual void print(ostream &os) { os << basename << "base" << endl; }
private:
string basename;
};
class derived :public base {
public:
void print(ostream &os) { base::print(os); os << " " << i << "derived"<<endl; }
private:
int i;
};
int main()
{
base bobj;
derived dobj;
base *bp1 = &bobj;
base *bp2 = &dobj;
base &br1 = bobj;
base &br2 = dobj;
bobj.print(cout); //base print()
dobj.print(cout); //derived print()
bp1->name(); //base name()
bp2->name(); //base name()
br1.print(cout); //base print()
br2.print(cout); //derived print()
}