C++primer 15.3节练习

练习15.11

 1 #include <iostream>
 2 #include <string>
 3 #include <utility>
 4 #include <memory>
 5 #include <vector>
 6 
 7 using namespace std;
 8 
 9 class Quote {
10 public:
11     Quote() = default;
12     Quote(const string &book, double sales_price) : bookNo(book), price(sales_price) {}
13     const string& isbn() const { return bookNo; }
14     virtual double net_price(size_t n) const{ return n * price; }
15     virtual void debug() { cout << "bookNo: " << bookNo << " price: " << price << endl; }
16     virtual ~Quote() = default;
17 private:
18     string bookNo;
19 protected:
20     double price = 0.0;
21 };
22 
23 class Bulk_quote : public Quote {
24 public:
25     Bulk_quote() = default;
26     Bulk_quote(const string& book, double p, size_t qty, double disc) : Quote(book, p), min_qty(qty), discount(disc) {}
27     double net_price(size_t n) const;
28     void debug() override { cout << "min_qty: " << min_qty << " discount: " << discount << endl; }
29 private:
30     size_t min_qty = 0;
31     double discount = 0.0;
32 };
33 
34 class lim_discount : public Quote {
35 public:
36     lim_discount() = default;
37     lim_discount(const string& book, double p, size_t lcount, double ldis) : Quote(book, p), lim_count(lcount), lim_dis(ldis) {}
38     double net_price(size_t n) const override;
39     void debug() override { cout << "lim_count: " << lim_count << " lim_dis: " << lim_dis << endl; }
40 private:
41     size_t lim_count = 0;
42     double lim_dis = 0.0;
43 };
44 double print_total(ostream& os, const Quote& item, size_t t);
45 
46 int main()
47 {
48     Quote q1;
49     Quote q2("C++ primer", 128.00);
50     Bulk_quote b1;
51     Bulk_quote b2("C++ primer", 128.00, 5, 0.4);
52     print_total(cout, q1, 6);
53     print_total(cout, q2, 6);
54     print_total(cout, b1, 6);
55     print_total(cout, b2, 6);
56     lim_discount l1("C++ primer", 128.00, 10, 0.5);
57     print_total(cout, l1, 9);
58     print_total(cout, l1, 11);
59     q2.debug();
60     system("pause");
61     return 0;
62 }
63 
64 double print_total(ostream & os, const Quote &item, size_t t)
65 {
66     double ret = item.net_price(t);
67     os << "ISBN: " << item.isbn() << " # sold: " << t << " total due: " << ret << endl;
68     return ret;
69 }
70 
71 double Bulk_quote::net_price(size_t n) const
72 {
73     if (n >= min_qty)
74         return n * (1 - discount) * price;
75     else
76         return n * price;
77 }
78 
79 double lim_discount::net_price(size_t n) const
80 {
81     if (n <= lim_count)
82         return n * (1 - lim_dis) * price;
83     else
84         return Quote::net_price(n);
85 }

练习15.12

有必要,override:在C+=11新标准中我们可以使用override关键字来说明派生类中的虚函数。这么做的好处是在使得我们的意图更加清晰明确地告诉编译器我们想要覆盖掉已存在的虚函数。如果定义了一个虚函数与基类中的名字相同但是形参列表不同,在不使用override关键字的时候这种函数定义是合法的,在使用了override关键字之后这种行为是非法的,编译器会提示出错。final:如果我们将某个函数定义成final,则不允许后续的派生类来覆盖这个函数,否则会报错。因此同时将一个成员函数声明成override和final能够使我们的意图更加清晰。

练习15.13

print函数的作用是打印出所有的数据成员(包括基类),所以在派生类覆盖基类的虚函数时出现问题,该处的print(os)在运行时被解析为对派生类版本自身的调用,从而导致无限循环;可改为

1 void print(ostream& os)
2 {
3   base::print(os);
4   os << " " << i;    
5 }

练习15.14

a)第一个

b)第二个

c)调用基类的name函数,bp1是一个指向基类的指针

d)非虚函数,导致bp2只有基类的数据成员,所以调用的是基类的name函数

e)第一个print

f)第二个print(这里涉及动态绑定)注意是虚函数,被调用的函数是与绑定到指针或引用上的对象的动态类型相匹配的那一个。贴一段代码

 1 #include <iostream>
 2 #include <string>
 3 using namespace std;
 4 
 5 class base {
 6 public:
 7     base() = default;
 8     base(const string& s) : basename(s) {}
 9     virtual void print(ostream &os) { os << basename; }
10 private:
11     string basename;
12 };
13 
14 class derived : public base {
15 public: 
16     derived() = default;
17     derived(const string& s, int j) : base(s), i(j) {}
18     void print(ostream &os) { base::print(os); os << " " << i; }
19 private:
20     int i;
21 };
22 
23 int main()
24 {
25     base bobj("hello");
26     derived dobj("world", 3);
27     base &br2 = dobj;
28     base *bp2 = &dobj;
29     bp2->print(cout);
30     //br2.print(cout);
31     system("pause");
32     return 0;
33 }

 

posted @ 2017-09-14 20:18  五月份小姐  阅读(310)  评论(0编辑  收藏  举报