A member function should be dynamically bound by preceding its
declaration.
A virtual member in a base class expects its derived class define its
own version. In particular base classes ordinarily should define a
virtual destructor, even if it does no work.
虚成员函数(virtual member function)是在类的声明中使用关键字
virtual 声明的成员函数。虚成员函数允许派生类(derived
class)覆盖(override)基类(base
class)中的同名函数,实现多态性(polymorphism)。
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 github.com/pezy/Cpp-Primer Quote class and print_total function If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 github.com/pezy/Cpp-Primer Bulk_quote class If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
Define a class that implements a limited discount strategy, which
applies a discount to books purchased up to a given limit. If the number
of copies exceeds that limit, the normal price applies to those
purchased beyond the limit.
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 github.com/pezy/Cpp-Primer Limit_quote class If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
static type: Type with which a variable is defined or that an
expression yields. Static type is known at compile
time.
dynamic type: Type of an object at run time. The
dynamic type of an object to which a reference refers or to which a
pointer points may differ from the static type of the reference or
pointer.
When is it possible for an expression’s static type to differ from
its dynamic type? Give three examples in which the static and dynamic
type differ.
A pointer or reference to a base-class type can refer to an to object
of derived type. In such cases the static type is reference (or pointer)
to base, but the dynamic type is reference (or pointer) to derived.
Sure. override means overriding the same name virtual
function in base class. final means preventing any
overriding this virtual function by any derived classes that are more
lower at the hierarchy.
Given the following classes, explain each print function:
1 2 3 4 5 6 7 8 9 10 11 12 13
classbase { public: string name(){ return basename; } virtualvoidprint(ostream &os){ os << basename; } private: string basename; }; classderived : public base { public: voidprint(ostream &os){ print(os); os << " " << i; } private: int i; };
If there is a problem in this code, how would you fix it?
The print in derived::print wanted to call
the print from the base class. However, the class scope
base:: was omitted. As a result, it will cause an infinite
recursion.
Fixed:
1
voidprint(ostream &os){ base::print(os); os << " " << i; }
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 github.com/pezy/Cpp-Primer Disc_quote If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 github.com/pezy/Cpp-Primer Limit_quote class inherit from Disc_quote If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
Choose one of the following general abstractions containing a family
of types (or choose one of your own). Organize the types into an
inheritance hierarchy:
Graphical file formats (such as gif, tiff, jpeg, bmp)
Geometric primitives (such as box, circle, sphere, cone)
C++ language types (such as class, function, member function)
选择以下包含一组类型的通用抽象(或选择您自己的抽象)。将这些类型组织成一个继承层次结构:
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 github.com/pezy/Cpp-Primer Geomtric Primitives box, circle, sphere, cone If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
Without it, when building the upper codes, the compiler would
conplain that:
1 2 3 4 5 6
error: use of deleted function 'Bulk_quote::Bulk_quote()' Bulk_quote b_quote; ^ 'Bulk_quote::Bulk_quote()' is implicitly deleted because the default definition would be ill-formed: Bulk_quote() = default; ^
The reason is that a constructor taking 4 parameters has been
defined, which prevented the compiler generate synthesized version
default constructor. As a result, the default constructor of any class
derived from it has been defined as deleted. Thus the default
constructor must be defined explicitly so that the derived classes can
call it when executing its default constructor.
Define the Quote and Bulk_quote
copy-control members to do the same job as the synthesized versions.
Give them and the other constructors print statements that identify
which function is running. Write programs using these classes and
predict what objects will be created and destroyed. Compare your
predictions with the output and continue experimenting until your
predictions are reliably correct.
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 https://github.com/pezy/Cpp-Primer Quote class 1. define copy-control members to do the same job as the synthesized versions. 2. Print function name to trace the running. If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 https://github.com/pezy/Cpp-Primer Disc_quote class 1. define copy-control members to do the same job as the synthesized versions. 2. Print function name to trace the running. If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 https://github.com/pezy/Cpp-Primer Bulk_quote inherited constructors from EX15::Disc_quote If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
double total = std::accumulate(vecQuote.cbegin(), vecQuote.cend(),0.0, [](double ret, const Quote &obj){ return ret += obj.net_price(5); });
// total price in the vector. std::cout << "total in the vector: " << total << std::endl; }
Output:
1 2
bulk_quote's total: 325 total in the vector: 500
Exercise 15.29
Repeat your program, but this time store shared_ptrs to
objects of type Quote. Explain any discrepancy in the sum
generated by the this version and the previous program. If there is no
discrepancy, explain why there isn’t one.
/* ================================================================================= C++ Primer 5th Exercise Answer Source Code Copyright (C) 2014-2015 https://github.com/pezy/Cpp-Primer Basket. If you have questions, try to connect with me: pezy<urbancpz@gmail.com> ================================================================================= */
inlinedoubleBasket::total_receipt(std::ostream &os)const{ auto sum = 0.0; for (auto iter = items.cbegin(); iter != items.cend(); iter = items.upper_bound(*iter)) { sum += print_total(os, **iter, items.count(*iter)); } os << "Total Sale: " << sum << std::endl; return sum; } }
购物篮内部使用了 std::multiset
容器来存储销售物品的指针,并且提供了一个用于比较指针的比较函数
compare。在 total_receipt 函数中,使用
print_total 函数计算每种物品的销售额,并将结果累加到
sum 中,然后打印总销售额。
这个类的设计允许用户添加不同类型的销售物品,并根据每种物品的销售数量计算总销售额。
Exercise 15.32
What happens when an object of type Query is copied,
moved, assigned, and destroyed?
copy: While being copied, the synthesized copy
constructor is called. It copies the data member into the new object.
Since in this case, the data member is a shared pointer, while copying,
the corresponding shared pointer points to the same address and the use
count from the both shared pointer becomes 2.
move: while being moved, the synthesized move
constructor is called. It moves the data member into the new object. In
this case, the shared pointer from the newly created object will point
to the address to which the original shared pointer pointed. After the
move operation, the use count of the shared pointer in the new object is
1, whereas the pointer from the original object becomes
nullptr.
copy assignment: The synthesized copy assignment
will be called. The outcome of this operation is identical with the copy
operation.
move assignment: The synthesized move assignment
will be called. The rest is the same as the move operation.
destroy: The synthesized destructor will be called.
It will call the destructor of shared_ptr which decrements
the use count. If the count becomes zero, the destructor from
shared_ptr will delete the resources it point to.