我是靠谱客的博主 傻傻万宝路,这篇文章主要介绍C++Prime 第十五章C++Prime 第十五章,现在分享给大家,希望可以做个参考。

C++Prime 第十五章

练习15.1

虚成员:基类希望派生类覆盖的成员函数.任何构造函数之外的非静态函数都可以是虚函数.

练习15.2

protected: 允许派生类访问
private:不允许

练习15.3

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#pragma once #include <iostream> #include <vector> using namespace std; class Quote { public: Quote() = default; Quote(const string& book, double sales_price) :bookNo(book), price(sales_price) {} string isbn()const { return bookNo; } virtual double net_price(size_t n)const { return n * price; } virtual ~Quote() = default; //对析构函数进行动态绑定 private: string bookNo; protected: double price = 0.0; }; class Bulk_quote :public Quote { public: double net_price(size_t n)const override; }; double print_total(ostream& os, const Quote& item, size_t n) { //可以调用Quote::net_price //也可以调用Bulk_quote::net_price double ret = item.net_price(n); os << "ISBN" << item.isbn() << " # sold: " << n << " total due: " << ret << endl; }

练习15.4

(a) 不能派生自己
(b)ok
© 类派生列表不可出现在声明语句中.

练习15.5

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#pragma once #include <iostream> #include <vector> using namespace std; class Quote { public: Quote() = default; Quote(const string& book, double sales_price) :bookNo(book), price(sales_price) {} string isbn()const { return bookNo; } virtual double net_price(size_t n)const { return n * price; } virtual ~Quote() = default; //对析构函数进行动态绑定 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) { } double net_price(size_t n)const override; private: size_t min_qty = 0;//使用折扣政策的最低购买量 double discount = 0.0;//以小数表示的折扣额 }; double print_total(ostream& os, const Quote& item, size_t n) { //可以调用Quote::net_price //也可以调用Bulk_quote::net_price double ret = item.net_price(n); os << "ISBN" << item.isbn() << " # sold: " << n << " total due: " << ret << endl; }

练习15.6

复制代码
1
2
3
4
5
6
7
8
9
int main() { Quote q; Bulk_quote bq; print_total(cout, q, 3); print_total(cout, bq, 4); return 0; }

练习15.7

复制代码
1
2
3
4
5
6
7
8
9
10
11
class my_Bulk_quote :public Bulk_quote { public: my_Bulk_quote() = default; my_Bulk_quote(const string& book, double p, size_t qty, double disc, size_t m) :Bulk_quote(book, p, qty, disc), max_qty(m) { } double net_price(size_t n)const override; private: size_t max_qty = 0; };
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "Quote.h" double Bulk_quote::net_price(size_t n) const { if (n >= min_qty) return n * (1 - discount) * price; else return n * price; } double my_Bulk_quote::net_price(size_t n) const { if (n >= max_qty) return (n - max_qty) * price + Bulk_quote::net_price(max_qty); return Bulk_quote::net_price(n);; }

练习15.8

静态类型:编译时已知,它是变量声明时的类型或表达式生成的类型.
动态类型:运行时才知道,是变量或表达式表示的内存中的对象的类型

练习15.9

基类的指针或引用的静态类型可能和其动态类型不一致.

复制代码
1
2
3
4
5
Quote q1; Bulk_quote q2; Quote &p1 = q2; Quote* p2 = &q2;

练习15.10

ifstream派生自istream,故其对象可以当成istream来使用

练习15.11

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() { Quote q("倚天屠龙记",10); Bulk_quote bq("降魔传",10,20,0.8); my_Bulk_quote my_bq("系游", 5, 20, 0.9, 20); q.debug(); cout << endl; bq.debug(); cout << endl; my_bq.debug(); cout << endl; return 0; }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#pragma once #include <iostream> #include <vector> using namespace std; class Quote { public: Quote() = default; Quote(const string& book, double sales_price) :bookNo(book), price(sales_price) {} string isbn()const { return bookNo; } virtual double net_price(size_t n)const { return n * price; } virtual ~Quote() = default; //对析构函数进行动态绑定 virtual void debug() { cout << "书名: "<<bookNo << ",单价: " << price; } 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) { } double net_price(size_t n)const override; void debug() { Quote::debug(); cout << ",折扣政策的最低购买量: " << min_qty << ",折扣额: " << discount; } private: size_t min_qty = 0;//使用折扣政策的最低购买量 double discount = 0.0;//以小数表示的折扣额 }; class my_Bulk_quote :public Bulk_quote { public: my_Bulk_quote() = default; my_Bulk_quote(const string& book, double p, size_t qty, double disc, size_t m) :Bulk_quote(book, p, qty, disc), max_qty(m) { } auto net_price(size_t n) const ->double override; void debug() { Bulk_quote::debug(); cout << ",最大限额量: " << max_qty; } private: size_t max_qty = 0; };

练习15.12

没有必要.假如是一个大于两层的继承体系.声明override表示将某个成员函数覆盖了,难保该类的派生类(第三层的继承类)不继续覆盖该成员函数,所以如果不是确信不会对其进行覆盖的情况下,不要用final.

练习15.13

有,无限递归,加上类限定符即可

练习15.14

(a)基类
(b)派生类
©基类
(d)派生类
(e)基类
(f)派生类

练习15.15

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Disc_quote :public Quote { public: Disc_quote() = default; Disc_quote(const string& book, double price, size_t qty, double disc) :Quote(book, price), quantity(qty), discount(disc) { } double net_price(size_t)const = 0; protected: size_t quantity = 0; //折扣适用的购买量 double discount = 0; //表示折扣的小数值 }; class Bulk_quote :public Disc_quote { public: Bulk_quote() = default; Bulk_quote(const string& book, double p, size_t qty, double disc) :Disc_quote(book, p, qty, disc){ } double net_price(size_t n)const override; };
复制代码
1
2
3
4
5
6
7
8
double Bulk_quote::net_price(size_t n) const { if (n >= quantity) return n * (1 - discount) * price; else return n * price; }

练习15.16

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
class my_Bulk_quote :public Disc_quote { public: my_Bulk_quote() = default; my_Bulk_quote(const string& book, double p, size_t qty, double disc, size_t m) :Disc_quote(book, p, qty, disc), max_qty(m) { } auto net_price(size_t n) const ->double override; private: size_t max_qty = 0; };
复制代码
1
2
3
4
5
6
7
double my_Bulk_quote::net_price(size_t n) const { if (n >= max_qty) return (n - max_qty) * price + max_qty * (1 - discount) * price; return n * (1 - discount) * price;; }

练习15.17

不可以定义纯虚拟基类的对象

练习15.18

Base *p = &d1; //合法,基类指针或引用可以指向公有派生类.
p = &d2; //不合法,基类的指针或引用可以指向公有派生的类对象
p = &d3; //不合法,同上
p = &dd1; //合法,基类指针或引用可以指向公有派生类

练习15.19

Derived_from_private是错误的.
第二层的派生类肯定是毫无问题的,第三层的派生类必须继承自第二层公有或派生的类,才可以向基类转换

练习15.20

正确

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main() { pub_derive d1; priv_derive d2; prot_derive d3; derived_from_private dd2; derived_from_public dd1; derived_from_protected dd3; myBase* p = &d1; //p = &d2; //p = &d3; p = &dd1; //p = &dd2; //p = &dd3; return 0; }

练习15.21

练习15.22

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#pragma once #include <iostream> #include <cmath> const double PI = 3.141592657; class Shape//ABC { public: Shape() = default; //默认构造函数 //其他函数无需定义 virtual ~Shape() {}; //虚析构函数 public: //成员函数 double get_area() const; //获得该图形的面积 virtual void calculate() = 0; //纯虚函数,计算相关数据 virtual void debug() const = 0; //输出所有数据 protected: double area = 0; //面积 }; class Square :public Shape { public: Square(double n) :side_len(n) { calculate(); } //使用边长进行构造 Square() = default; //默认构造,边长初始化为0 //其他拷贝控制函数不需要 ~Square() override { }; //虚析构,不用定义任何操作 public: void calculate() override; //重写 void debug() const override; //输出所有数据 double get_perimeter() const; //获得该图形的周长 private: double side_len = 0; //边长 double perimeter = 0; //周长 }; class Round :public Shape { public: Round() = default; Round(double r) :radiu(r) { calculate(); } ~Round()override { } public: void calculate() override; //纯虚函数,计算面积和周长 void debug()const override; double get_perimeter() const; //获得该图形的周长 private: double radiu = 0; //圆的半径 double perimeter = 0; }; class Ball :public Shape { public: //类的基础 Ball() = default; Ball(double r) :radiu(r) { calculate(); } ~Ball()override { } public: //功能实现 void calculate()override; //计算 void debug()const override; double get_volumn()const; //获得球的体积 private: double radiu = 0; //半径 double volumn = 0; //体积 }; class Cone :public Shape { public: Cone() = default; Cone(double r, double h) :radiu(r), height(h) { calculate(); } ~Cone() override { } public: void calculate()override; void debug() const override; double get_volumn(); private: double radiu = 0; double height = 0; double volumn = 0; double mother_line = 0; };
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "Shape.h" void Square::calculate() { area = side_len * side_len; perimeter = 4 * side_len; return; } void Square::debug() const { std::cout << "这是个方块!边长是: " << side_len << ",周长是: " << perimeter << ",面积是: " << area << std::endl; } double Square::get_perimeter() const { return perimeter; } double Shape::get_area() const { return area; } void Round::calculate() { area = PI * radiu * radiu; perimeter = 2 * PI * radiu; return; } void Round::debug() const { std::cout << "这是个圆!半径是: " << radiu << ",周长是: " << perimeter << ",面积是: " << area << std::endl; } double Round::get_perimeter() const { return perimeter; } void Ball::calculate() { area = 4 * PI * radiu * radiu; volumn = PI * radiu * radiu * radiu * 4 / 3; return; } void Ball::debug() const { std::cout << "这是个球!半径是: " << radiu << ",面积是: " << area <<",体积是: "<<volumn << std::endl; } double Ball::get_volumn() const { return volumn; } void Cone::calculate() { mother_line = sqrt(height * height + radiu * radiu); area = PI * radiu * mother_line + PI * radiu * radiu; volumn = PI * radiu * radiu * height / 3; return; } void Cone::debug() const { std::cout << "这是个圆锥!半径是: " << radiu <<",高度是: "<<height <<",母线长是: "<<mother_line << ",体积是: " << volumn << ",面积是: " << area << std::endl; } double Cone::get_volumn() { return volumn; }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
int main() { Square s(2); Round r(3); Ball b(4); Cone c(6, 7); vector<Shape* > pvec{&s,&r,&b,&c};//基类指针可以指向公有派生类对象 for (auto p : pvec) p->debug(); return 0; }

输出:

复制代码
1
2
3
4
5
这是个方块!边长是: 2,周长是: 8,面积是: 4 这是个圆!半径是: 3,周长是: 18.8496,面积是: 28.2743 这是个球!半径是: 4,面积是: 201.062,体积是: 268.083 这是个圆锥!半径是: 6,高度是: 7,母线长是: 9.21954,体积是: 263.894,面积是: 286.882

练习15.23

去掉形参int.
Base bobj; D1 d1obj; D2 d2obj;
Base *bp1 = &bobj, *bp2 = &d1obj, *bp3 = &d2obj;

bp1->fcn(); //调用Base::fcn
bp2->fcn(); //调用Base::fcn()
bp3->fcn(); //调用D2::fcn

bp2->f2(); //报错,Base没有成员函数f2()
d1p->f2(); //调用D1::f2()
d2p->f2(); //调用D2::f2()

p1->fcn(42); //报错,base没有成员函数fcn(int)
p2->fcn(42); //报错,(未修改前不报错)
p3->fcn(42); //调用D2::fcn(int)

练习15.24

继承体系中的类分配了资源,该基类必须定义虚析构函数.
释放所分配的资源.

练习15.25

如果不给Disc_quote定义一个默认的构造函数,那么因为定义了自定义的构造函数,Disc_quote将没有默认构造函数.
那么它的派生类的默认构造函数将是被删除的.
将无法使用默认构造函数.

练习15.26

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#pragma once #include <iostream> #include <vector> using namespace std; class Quote { public: Quote(const Quote& q) ; Quote(Quote&& q) ; Quote& operator=(const Quote& q) ; Quote& operator=(Quote&& q); public: Quote(const string& book = " ", double sales_price = 0.0) :bookNo(book), price(sales_price) { cout << "使用Quote的构造函数n"; } string isbn()const { return bookNo; } virtual double net_price(size_t n)const { return n * price; } virtual ~Quote() = default; //对析构函数进行动态绑定 virtual void debug() { cout << "书名: "<<bookNo << ",单价: " << price; } private: string bookNo; protected: double price = 0.0; }; class Disc_quote :public Quote { public: Disc_quote(const Disc_quote& d); Disc_quote(Disc_quote&& d); Disc_quote& operator=(const Disc_quote& d); Disc_quote& operator=(Disc_quote && d); public: Disc_quote() = default; Disc_quote(const string& book, double price, size_t qty, double disc) :Quote(book, price), quantity(qty), discount(disc) { } double net_price(size_t)const = 0; protected: size_t quantity = 0; //折扣适用的购买量 double discount = 0; //表示折扣的小数值 }; class Bulk_quote :public Disc_quote { public: Bulk_quote() = default; Bulk_quote(const string& book, double p, size_t qty, double disc) :Disc_quote(book, p, qty, disc){ } double net_price(size_t n)const override; }; class my_Bulk_quote :public Disc_quote { public: my_Bulk_quote() = default; my_Bulk_quote(const string& book, double p, size_t qty, double disc, size_t m) :Disc_quote(book, p, qty, disc), max_qty(m) { } auto net_price(size_t n) const ->double override; //void debug() { Bulk_quote::debug(); cout << ",最大限额量: " << max_qty; } private: size_t max_qty = 0; };

练习15.27

练习15.28

练习15.29

复制代码
1
2
3
4
5
6
7
8
vector<shared_ptr<Quote> > v; v.push_back(make_shared<Bulk_quote>("0-123-12", 50, 10, 0.25)); v.push_back(make_shared<Bulk_quote>("0-sdf", 20, 15, 0.27)); double sum = 0; for (const auto& p : v) sum += p->net_price(8); cout << sum << endl;

练习15.30

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#pragma once #include <vector> #include <iostream> #include <set> #include "Quote.h" using namespace std; class Basket { public: void add_item(const Quote& sales) { items.insert(shared_ptr<Quote>(sales.clone())); } void add_item(Quote&& sales) { items.insert(shared_ptr<Quote>(std::move(sales).clone())); } void add_item(const shared_ptr<Quote>& sale) { items.insert(sale); } double total_receipt(ostream&)const; private: static bool compare(const shared_ptr<Quote> &lhs, const shared_ptr<Quote>& rhs ) { return lhs->isbn() < rhs->isbn(); } multiset<shared_ptr<Quote>, decltype(compare)* > items{ compare }; };

练习15.31

(a)Query(s1)生成一个WordQuery对象.然后生成一个OrQuery,右侧先生成WordQuery,然后变成NotQuery,最后生成一个AndQuery
(b)先生成WordQuery,然后NOtQuery,然后AndQuery最后NotQuery

练习15.32

最后一个例子及其剩下的题目暂时不做了,很久很久后会来补上的.

最后

以上就是傻傻万宝路最近收集整理的关于C++Prime 第十五章C++Prime 第十五章的全部内容,更多相关C++Prime内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(57)

评论列表共有 0 条评论

立即
投稿
返回
顶部