15.23 修改代码:
class Base {
public:
virtual int fcn();
};
class D1 : public Base {
int fcn(); //覆盖而非隐藏
virtual void f2();
};
class D2 : public D1 {
public:
int fnc(int);
int fcn();
void f2();
};
调用语句的解析:
Base bobj; D1 d1obj; D2 d2obj;
Base *bp1 = &bobj; *bp2 = &d1obj; *bp3 = &d2obj;
bp1->fcn(); //Base::fcn
bp2->fcn(); //D1::fcn
bp3->fcn(); //D2::fcn
D1 *d1p = &d1obj; D2 *d2p = &d2obj;
bp2->f2(); //错误,Base没有f2()
d1p->f2(); //D1::f2()
d2p->f2(); //D2::f2()
Base *p1 = &d2obj; D1 *p2 = &d2obj; D2 *p3 = &d2obj;
p1->fcn(42); //错误,Base没有fcn(int)
p2->fcn(42); //错误,D1没有fcn(int)
p3->fcn(42); //D2::fcn(int)
15.24 基类需要虚析构函数,在静态类型和动态类型不同时,保证运行正确的析构函数版本;虚析构函数必须清除本类中定义的数据成员,可以定义为默认的。
15.25 Disc_quote的默认构造函数会调用Quote的默认构造函数,完成基类部分的成员初始化工作;如果去掉该默认构造函数,Bulk_quote的默认构造函数将无法完成其基类部分的初始化工作。
15.26 Quote.h文件代码:
#ifndef QUOTE_H
#define QUOTE_H
#include <iostream>
using namespace std;
class Quote {
public:
Quote() = default;
Quote(const string &book, double sales_price):
bookNo(book), price(sales_price) { cout << "Quote construct" << endl; }
Quote(const Quote &q):
bookNo(q.bookNo), price(q.price) { cout << "Quote copy construct" << endl; }
Quote(Quote &&q):
bookNo(std::move(q.bookNo)), price(std::move(q.price)) { cout << "Quote move construct" << endl; }
Quote& operator=(const Quote &q) {
bookNo = q.bookNo;
price = q.price;
cout << "Quote operator = " << endl;
return *this;
}
Quote& operator=(Quote &&q) {
bookNo = std::move(q.bookNo);
price = std::move(price);
cout << "Quote operator move = " << endl;
}
string isbn() const { return bookNo; };
virtual double net_price(size_t n) const
{ return n * price; }
virtual void debug() { cout << "bookNo: "<< bookNo << " price: " << price << endl; }
virtual ~Quote() {
cout << "Quote destructor" << endl;
}
private:
string bookNo;
protected:
double price = 0.0;
};
class Bulk_quote: public Quote {
public:
Bulk_quote() = default;
Bulk_quote(const string &book, double p, size_t qty, double disc):
Quote(book, p), min_qty(qty), discount(disc) { cout << "Bulk_quote construct" << endl; }
Bulk_quote(const Bulk_quote &b):
Quote(b), min_qty(b.min_qty), discount(b.discount) { cout << "Bulk_quote copy construct" << endl; }
Bulk_quote(Bulk_quote &&b):
Quote(std::move(b)), min_qty(std::move(b.min_qty)), discount(std::move(b.discount)) {
cout << "Bulk_quote copy construct" << endl;
}
Bulk_quote& operator=(const Bulk_quote &b) {
Quote::operator=(b);
min_qty = b.min_qty;
discount = b.discount;
cout << "Bulk_quote operator = construct" << endl;
return *this;
}
Bulk_quote& operator=(Bulk_quote &&b) {
Quote::operator=(std::move(b));
min_qty = std::move(b.min_qty);
discount = std::move(b.discount);
cout << "Bulk_quote operator move = construct" << endl;
return *this;
}
~Bulk_quote() {
cout << "Bulk_quote destructor" << endl;
}
void debug() override { Quote::debug(); cout << "min_qty= " << min_qty << " discount= " <<
discount << endl; }
double net_price(size_t) const override;
private:
size_t min_qty = 0;
double discount = 0.0;
};
double print_total(ostream &os, const Quote &item, size_t n);
#endif
Quote.cc 文件:
#include <iostream>
#include "Quote.h"
using namespace std;
double
Bulk_quote::net_price(size_t cnt) const
{
if (cnt >= min_qty)
return cnt * price * (1 - discount);
else
return cnt * price;
}
double print_total(ostream &os, const Quote &item, size_t n)
{
double ret = item.net_price(n);
os << "ISBN: " << item.isbn() << " # sold: " << n <<
" total due: " << ret << endl;
return ret;
}
测试主程序:
#include <iostream>
#include "Quote.h"
using namespace std;
int main()
{
Quote q1("a1", 8.9);
Bulk_quote q2("a2", 7.7, 10, 0.2);
Quote q3(q1);
Bulk_quote q4(q2);
q3 = q1;
q4 = q2;
q3 = std::move(q1);
q4 = std::move(q2);
print_total(cout, q1, 10);
print_total(cout, q2, 20);
print_total(cout, q3, 10);
print_total(cout, q4, 20);
return 0;
}
15.27
class Bulk_quote: public Disc_quote {
public:
Bulk_quote() = default;
using Disc_quote::Disc_quote;
double net_price(size_t) const override;
private:
size_t min_qty = 0;
double discount = 0.0;
};