Skip to content

Commit 95df501

Browse files
author
Jaege
committed
Add soultions to second half of exercises in chapter 15.
1 parent 9df6f6e commit 95df501

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+4395
-5
lines changed

README.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,11 +143,11 @@ This repo is the solutions to exercises in book [_C++ Primer_ (5th Edition)](htt
143143

144144
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10
145145
--:|--:|--:|--:|--:|--:|--:|--:|--:|--:
146-
[1](ch15/15.1.cpp)|[2](ch15/15.2.cpp)|[3](ch15/15.3.cpp)|[4](ch15/15.4.cpp)|[5](ch15/15.5.cpp)|[6](ch15/15.6.cpp)|[7](ch15/15.7.cpp)|[8](ch15/15.8.cpp)|[9](ch15/15.9.cpp)|[10](ch15/15.10.cpp)|
147-
[11](ch15/15.11.cpp)|[12](ch15/15.12.cpp)|[13](ch15/15.13.cpp)|[14](ch15/15.14.cpp)|[15](ch15/15.15.cpp)|[16](ch15/15.16.cpp)|[17](ch15/15.17.cpp)|[18](ch15/15.18.cpp)|[19](ch15/15.19.cpp)|[20](ch15/15.20.cpp)|
148-
[21](ch15/15.21.cpp)|[22](ch15/15.22.cpp)|[23](ch15/15.23.cpp)|[24](ch15/15.24.cpp)|[25](ch15/15.25.cpp)|[26](ch15/15.26.cpp)|[27](ch15/15.27.cpp)|[28](ch15/15.28.cpp)|[29](ch15/15.29.cpp)|[30](ch15/15.30.cpp)|
149-
[31](ch15/15.31.cpp)|[32](ch15/15.32.cpp)|[33](ch15/15.33.cpp)|[34](ch15/15.34.cpp)|[35](ch15/15.35.cpp)|[36](ch15/15.36.cpp)|[37](ch15/15.37.cpp)|[38](ch15/15.38.cpp)|[39](ch15/15.39.cpp)|[40](ch15/15.40.cpp)|
150-
[41](ch15/15.41.cpp)|[42](ch15/15.42.cpp)
146+
[1](ch15/15.1.md)|[2](ch15/15.2.md)|[3](ch15/15.3.cpp)|[4](ch15/15.4.md)|[5](ch15/15.5.md)|[6](ch15/15.6.md)|[7](ch15/15.7.cpp)|[8](ch15/15.8.md)|[9](ch15/15.9.md)|[10](ch15/15.10.md)|
147+
[11](ch15/15.11.cpp)|[12](ch15/15.12.md)|[13](ch15/15.13.md)|[14](ch15/15.14.cpp)|[15](ch15/15.15.cpp)|[16](ch15/15.16.md)|[17](ch15/15.17.cpp)|[18](ch15/15.18.cpp)|[19](ch15/15.19.cpp)|[20](ch15/15.20.md)|
148+
[21](ch15/15.21.cpp)|[22](ch15/15.22.cpp)|[23](ch15/15.23.cpp)|[24](ch15/15.24.md)|[25](ch15/15.25.md)|[26](ch15/15.26.cpp)|[27](ch15/15.27.cpp)|[28](ch15/15.28.cpp)|[29](ch15/15.29.cpp)|[30](ch15/15.30.cpp)|
149+
[31](ch15/15.31.md)|[32](ch15/15.32.md)|[33](ch15/15.33.md)|[34](ch15/15.34.md)|[35](ch15/15.35)|[36](ch15/15.36.md)|[37](ch15/15.37)|[38](ch15/15.38.md)|[39](ch15/15.39)|[40](ch15/15.40.md)|
150+
[41](ch15/15.41)|[42](ch15/15.42)
151151

152152
<!---
153153
#### Chapter 16 [Templates and Generic Programming](ch16)

ch15/15.23.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <iostream>
2+
using std::cout; using std::endl;
3+
4+
class Base {
5+
public:
6+
virtual int fcn() { cout << "Base::fcn" << endl; return 0; }
7+
};
8+
9+
class D1 : public Base {
10+
public:
11+
//int fcn(int);
12+
int fcn() override { // fixed by removing parameter and add keyword override
13+
cout << "D1::fcn" << endl; return 0;
14+
}
15+
virtual void f2() { cout << "D1::f2" << endl; }
16+
};
17+
18+
class D2 : public D1 {
19+
public:
20+
int fcn(int) { cout << "D2::fcn(int)" << endl; return 0; }
21+
int fcn() { cout << "D2::fcn" << endl; return 0; }
22+
void f2() { cout << "D2::f2" << endl; }
23+
};
24+
25+
int main() {
26+
Base bobj; D1 d1obj; D2 d2obj;
27+
Base *bp1 = &bobj, *bp2 = &d1obj, *bp3 = &d2obj;
28+
bp1->fcn(); // virtual call, will call Base::fcn at run time
29+
bp2->fcn(); // virtual call, will call D1::fcn at run time <--- changed
30+
bp3->fcn(); // virtual call, will call D2::fcn at run time
31+
32+
return 0;
33+
}

ch15/15.24.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
A base class usually needs a virtual destructor to allow objects in the inheritance hierarchy to be dynamically allocated. The virtual destructor must free dynamically alloacted resources in its class if so, otherwise, an empty virtual destructor is enough.

ch15/15.25.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Because if there exists any user-defined constructor, then there is no synthesized default constructor. And if we want to construct a default initialized `Bulk_quote` type object, all classes must have user-defined or synthesized default constructor in inheritance hierarchy. Thus we define a default constructor for `Disc_quote`.
2+
3+
If we remove that constructor, the complier will not synthesized one for us, thus we could only create `Bulk_quote` object by providing arguments consistent with other constructors.

ch15/15.26.cpp

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
// based on ex15.15
2+
#include <string>
3+
#include <iostream>
4+
5+
class Quote {
6+
public:
7+
Quote() {
8+
std::cout << "Quote" << std::endl;
9+
}
10+
11+
Quote(const std::string &book, double pri)
12+
: bookNo(book), price(pri) {
13+
std::cout << "Quote(const std::string &book, double pri)" << std::endl;
14+
}
15+
16+
virtual ~Quote() {
17+
std::cout << "~Quote" << std::endl;
18+
}
19+
Quote(const Quote &rhs) : price(rhs.price), bookNo(rhs.bookNo) {
20+
std::cout << "Quote(const Quote &rhs)" << std::endl;
21+
}
22+
Quote(Quote &&rhs) : price(std::move(rhs.price)),
23+
bookNo(std::move(rhs.bookNo)) {
24+
std::cout << "Quote(Quote &&rhs)" << std::endl;
25+
}
26+
Quote &operator=(const Quote &rhs) {
27+
std::cout << "operator=(const Quote &rhs)" << std::endl;
28+
price = rhs.price;
29+
bookNo = rhs.bookNo;
30+
return *this;
31+
}
32+
Quote &operator=(Quote &&rhs) {
33+
std::cout << "operator=(Quote &&rhs)" << std::endl;
34+
price = std::move(rhs.price);
35+
bookNo = std::move(rhs.bookNo);
36+
return *this;
37+
}
38+
39+
std::string isbn() const { return bookNo; }
40+
virtual double net_price(std::size_t n) const { return n * price; }
41+
42+
virtual std::ostream &debug(std::ostream &os) const {
43+
os << "Quote::bookNo " << bookNo << " Quote::price " << price;
44+
return os;
45+
}
46+
47+
protected:
48+
double price = 0.0;
49+
50+
private:
51+
std::string bookNo;
52+
};
53+
54+
class Disc_quote : public Quote {
55+
public:
56+
Disc_quote() {
57+
std::cout << "Disc_quote" << std::endl;
58+
}
59+
Disc_quote(const std::string &book, double pri,
60+
std::size_t qty, double disc)
61+
: Quote(book, pri), quantity(qty), discount(disc) {
62+
std::cout << "Disc_quote(const std::string &book, ... )" << std::endl;
63+
}
64+
65+
~Disc_quote() {
66+
std::cout << "~Disc_quote" << std::endl;
67+
}
68+
Disc_quote(const Disc_quote &rhs)
69+
: Quote(rhs), quantity(rhs.quantity), discount(rhs.discount) {
70+
std::cout << "Disc_quote(const Disc_quote &rhs)" << std::endl;
71+
}
72+
Disc_quote(Disc_quote &&rhs) : Quote(std::move(rhs)),
73+
quantity(std::move(rhs.quantity)),
74+
discount(std::move(rhs.discount)) {
75+
std::cout << "Disc_quote(Disc_quote &&rhs)" << std::endl;
76+
}
77+
Disc_quote &operator=(const Disc_quote &rhs) {
78+
Quote::operator=(rhs);
79+
std::cout << "operator=(const Disc_quote &rhs)" << std::endl;
80+
quantity = rhs.quantity;
81+
discount = rhs.discount;
82+
return *this;
83+
}
84+
Disc_quote &operator=(Disc_quote &&rhs) {
85+
Quote::operator=(std::move(rhs));
86+
std::cout << "operator=(Disc_quote &&rhs)" << std::endl;
87+
quantity = std::move(rhs.quantity);
88+
discount = std::move(rhs.discount);
89+
return *this;
90+
}
91+
92+
double net_price(std::size_t n) const = 0;
93+
94+
std::ostream &debug(std::ostream &os) const override {
95+
Quote::debug(os) << " Disc_quote::quantity " << quantity
96+
<< " Disc_quote::discount " << discount;
97+
return os;
98+
}
99+
100+
protected:
101+
std::size_t quantity = 0;
102+
double discount = 0.0;
103+
};
104+
105+
class Bulk_quote : public Disc_quote {
106+
public:
107+
Bulk_quote() = default;
108+
Bulk_quote(const std::string &book, double pri, std::size_t qty, double disc)
109+
: Disc_quote(book, pri, qty, disc) { }
110+
111+
double net_price(std::size_t n) const override {
112+
if (n >= quantity)
113+
return n * price * (1 - discount);
114+
else
115+
return n * price;
116+
}
117+
};
118+
119+
class Limit_quote : public Disc_quote {
120+
public:
121+
Limit_quote() = default;
122+
Limit_quote(const std::string &book, double pri, std::size_t qty, double disc)
123+
: Disc_quote(book, pri, qty, disc) { }
124+
125+
double net_price(std::size_t n) const override {
126+
if (n <= quantity)
127+
return n * price * (1 - discount);
128+
else
129+
return (n - quantity) * price + quantity * price * (1 - discount);
130+
}
131+
};
132+
133+
double print_total(std::ostream &os, const Quote &item, size_t n) {
134+
double ret = item.net_price(n);
135+
os << "ISBN: " << item.isbn() << " # sold: " << n << " total due: " << ret
136+
<< std::endl;
137+
return ret;
138+
}
139+
140+
int main() {
141+
Quote basic0;
142+
basic0.debug(std::cout) << '\n' << std::endl;
143+
144+
Quote basic1("abc", 5.5);
145+
basic1.debug(std::cout) << '\n' << std::endl;
146+
147+
Quote basic2(basic1);
148+
basic2.debug(std::cout) << '\n' << std::endl;
149+
150+
Quote basic3(std::move(basic2));
151+
basic3.debug(std::cout) << std::endl;
152+
basic2.debug(std::cout) << '\n' << std::endl;
153+
154+
basic2 = basic3;
155+
basic2.debug(std::cout) << '\n' << std::endl;
156+
157+
basic3 = std::move(basic1);
158+
basic3.debug(std::cout) << std::endl;
159+
basic1.debug(std::cout) << '\n' << std::endl;
160+
161+
std::cout << "============================" << std::endl;
162+
163+
Bulk_quote bulk0;
164+
bulk0.debug(std::cout) << '\n' << std::endl;
165+
166+
Bulk_quote bulk1("abc", 5.5, 10, 0.2);
167+
bulk1.debug(std::cout) << '\n' << std::endl;
168+
169+
Bulk_quote bulk2(bulk1);
170+
bulk2.debug(std::cout) << '\n' << std::endl;
171+
172+
Bulk_quote bulk3(std::move(bulk2));
173+
bulk3.debug(std::cout) << std::endl;
174+
bulk2.debug(std::cout) << '\n' << std::endl;
175+
176+
bulk2 = bulk3;
177+
bulk2.debug(std::cout) << '\n' << std::endl;
178+
179+
bulk3 = std::move(bulk1);
180+
bulk3.debug(std::cout) << std::endl;
181+
bulk1.debug(std::cout) << '\n' << std::endl;
182+
183+
std::cout << "============================" << std::endl;
184+
185+
Limit_quote limit0;
186+
limit0.debug(std::cout) << '\n' << std::endl;
187+
188+
Limit_quote limit1("abc", 5.5, 5, 0.1);
189+
limit1.debug(std::cout) << '\n' << std::endl;
190+
191+
Limit_quote limit2(limit1);
192+
limit2.debug(std::cout) << '\n' << std::endl;
193+
194+
Limit_quote limit3(std::move(limit2));
195+
limit3.debug(std::cout) << std::endl;
196+
limit2.debug(std::cout) << '\n' << std::endl;
197+
198+
limit2 = limit3;
199+
limit2.debug(std::cout) << '\n' << std::endl;
200+
201+
limit3 = std::move(limit1);
202+
limit3.debug(std::cout) << std::endl;
203+
limit1.debug(std::cout) << '\n' << std::endl;
204+
205+
return 0;
206+
}

0 commit comments

Comments
 (0)