From d4febf6d4573b14f9f6dc78caadb7103f7e73b8a Mon Sep 17 00:00:00 2001 From: jzplp Date: Sat, 3 Aug 2019 23:50:02 +0800 Subject: [PATCH] 16.1-16.11 --- Chapter-16/16.2.cpp | 19 ++++++++++ Chapter-16/16.3/Sales_data.cpp | 60 ++++++++++++++++++++++++++++++ Chapter-16/16.3/Sales_data.h | 50 +++++++++++++++++++++++++ Chapter-16/16.3/main.cpp | 20 ++++++++++ Chapter-16/16.4.cpp | 23 ++++++++++++ Chapter-16/16.5.cpp | 17 +++++++++ Chapter-16/16.6.cpp | 26 +++++++++++++ Chapter-16/16.7.cpp | 15 ++++++++ Chapter-16/chapter-16-answer.md | 66 +++++++++++++++++++++++++++++++++ 9 files changed, 296 insertions(+) create mode 100644 Chapter-16/16.2.cpp create mode 100644 Chapter-16/16.3/Sales_data.cpp create mode 100644 Chapter-16/16.3/Sales_data.h create mode 100644 Chapter-16/16.3/main.cpp create mode 100644 Chapter-16/16.4.cpp create mode 100644 Chapter-16/16.5.cpp create mode 100644 Chapter-16/16.6.cpp create mode 100644 Chapter-16/16.7.cpp diff --git a/Chapter-16/16.2.cpp b/Chapter-16/16.2.cpp new file mode 100644 index 0000000..a879f7d --- /dev/null +++ b/Chapter-16/16.2.cpp @@ -0,0 +1,19 @@ +#include +#include + +template +int compare(const T & v1, const T & v2) +{ + if(v1 < v2) + return -1; + if(v2 < v1) + return 1; + return 0; +} + +int main() +{ + std::cout << compare(1,2) << std::endl; + std::cout << compare(std::string("123"), std::string("123")) << std::endl; + return 0; +} diff --git a/Chapter-16/16.3/Sales_data.cpp b/Chapter-16/16.3/Sales_data.cpp new file mode 100644 index 0000000..ae7606d --- /dev/null +++ b/Chapter-16/16.3/Sales_data.cpp @@ -0,0 +1,60 @@ +#include +#include +#include "Sales_data.h" + +Sales_data & Sales_data::operator+=(const Sales_data & sa) +{ + amount += sa.amount; + totalPrice += sa.totalPrice; + return *this; +} + +Sales_data & Sales_data::operator=(const std::string & s) +{ + ISBN = s; + totalPrice = 0.0; + amount = 0; + return *this; +} + +inline double Sales_data::avg_price() const +{ + if(amount) + return totalPrice / amount; + return 0; +} + +Sales_data operator+(const Sales_data & sa, const Sales_data & sb) +{ + Sales_data sum = sa; + sum += sb; + return sum; +} + +std::istream & operator>>(std::istream & is, Sales_data & sa) +{ + double price = 0; + is >> sa.ISBN >> sa.amount >> price; + if(is) + sa.totalPrice = price * sa.amount; + else + sa = Sales_data(); + return is; +} + +std::ostream & operator<<(std::ostream & os, const Sales_data & sa) +{ + os << sa.isbn() << " " << sa.amount << " " << sa.totalPrice << " " << sa.avg_price(); + return os; +} + +bool operator==(const Sales_data &lhs, const Sales_data &rhs) +{ + return lhs.isbn() == rhs.isbn() && lhs.totalPrice == rhs.totalPrice && lhs.amount == rhs.amount; +} + +bool operator!=(const Sales_data &lhs, const Sales_data &rhs) +{ + return !(lhs == rhs); +} + diff --git a/Chapter-16/16.3/Sales_data.h b/Chapter-16/16.3/Sales_data.h new file mode 100644 index 0000000..b54c0cd --- /dev/null +++ b/Chapter-16/16.3/Sales_data.h @@ -0,0 +1,50 @@ +#ifndef SALES_DATA_H +#define SALES_DATA_H + +#include +#include + +struct Sales_data; + +Sales_data operator+(const Sales_data & sa, const Sales_data & sb); + +std::istream & operator>>(std::istream & is, Sales_data & sa); + +std::ostream & operator<<(std::ostream & os, const Sales_data & sa); + +bool operator==(const Sales_data &lhs, const Sales_data &rhs); +bool operator!=(const Sales_data &lhs, const Sales_data &rhs); + +class Sales_data +{ + +friend Sales_data operator+(const Sales_data & sa, const Sales_data & sb); +friend std::istream & operator>>(std::istream & is, Sales_data & sa); +friend std::ostream & operator<<(std::ostream & os, const Sales_data & sa); +friend bool operator==(const Sales_data &lhs, const Sales_data &rhs); +public: + + Sales_data() = default; + Sales_data(const std::string &s) : ISBN(s) { } + Sales_data(const std::string &s, int a, double t) : ISBN(s), amount(a), totalPrice(t * a) { } + Sales_data(std::istream &is) { is >> *this; } + + std::string isbn() const { return ISBN; } + Sales_data & operator+=(const Sales_data & sa); + Sales_data & operator=(const std::string & s); + + explicit operator double() const { return totalPrice; } + explicit operator std::string() const { return isbn(); } + +private: + + std::string ISBN; + double totalPrice = 0.0; + int amount = 0; + + inline double avg_price() const; +}; + +#endif + + diff --git a/Chapter-16/16.3/main.cpp b/Chapter-16/16.3/main.cpp new file mode 100644 index 0000000..cd1ddc6 --- /dev/null +++ b/Chapter-16/16.3/main.cpp @@ -0,0 +1,20 @@ +#include +#include "Sales_data.h" + +template +int compare(const T & v1, const T & v2) +{ + if(v1 < v2) + return -1; + if(v2 < v1) + return 1; + return 0; +} + +int main() +{ + Sales_data a("123",10, 20), b("123",10, 30); + + std::cout << compare(a,b) << std::endl; + return 0; +} diff --git a/Chapter-16/16.4.cpp b/Chapter-16/16.4.cpp new file mode 100644 index 0000000..38bb6b4 --- /dev/null +++ b/Chapter-16/16.4.cpp @@ -0,0 +1,23 @@ +#include +#include +#include + +template +T find(T beg,T end, const U & value) +{ + while(beg != end) + if (*beg == value) + return beg; + else + ++beg; + return end; +} + +int main() +{ + std::vector v1{1,2,34,5,66,77,56457,436,2,523,6,235}; + std::list l1{1,2,34,5,66,77,56457,436,2,523,6,235}; + std::cout << *find(v1.begin(), v1.end(), 6) << std::endl; + std::cout << *find(l1.cbegin(), l1.cend(), 6) << std::endl; + return 0; +} diff --git a/Chapter-16/16.5.cpp b/Chapter-16/16.5.cpp new file mode 100644 index 0000000..6562a6c --- /dev/null +++ b/Chapter-16/16.5.cpp @@ -0,0 +1,17 @@ +#include + +template +void print(const T (&arr)[U]) +{ + for(const T & i: arr) + std::cout << i << std::endl; +} + +int main() +{ + int arr1[4] = {1,2,3,4}; + double arr2[5] = {1,2,3,45,6}; + print(arr1); + print(arr2); + return 0; +} diff --git a/Chapter-16/16.6.cpp b/Chapter-16/16.6.cpp new file mode 100644 index 0000000..ce0e16a --- /dev/null +++ b/Chapter-16/16.6.cpp @@ -0,0 +1,26 @@ +#include + +template +T * begin(T (&arr)[U]) +{ + return &arr[0]; +} + +template +T * end(T (&arr)[U]) +{ + return &arr[U]; +} + +int main() +{ + int arr1[4] = {1,2,3,4}; + double arr2[5] = {1,2,3,45,6}; + for(int * p = begin(arr1); p != end(arr1); ++p) + std::cout << *p << " "; + std::cout << std::endl; + for(double * p = begin(arr2); p != end(arr2); ++p) + std::cout << *p << " "; + std::cout << std::endl; + return 0; +} diff --git a/Chapter-16/16.7.cpp b/Chapter-16/16.7.cpp new file mode 100644 index 0000000..c7c60d2 --- /dev/null +++ b/Chapter-16/16.7.cpp @@ -0,0 +1,15 @@ +#include + +template constexpr +unsigned len(T (&arr)[U]) +{ + return U; +} + +int main() +{ + int arr1[4] = {1,2,3,4}; + double arr2[5] = {1,2,3,45,6}; + std::cout << len(arr1) << " " << len(arr2) << std::endl; + return 0; +} diff --git a/Chapter-16/chapter-16-answer.md b/Chapter-16/chapter-16-answer.md index 5148096..dc59edf 100644 --- a/Chapter-16/chapter-16-answer.md +++ b/Chapter-16/chapter-16-answer.md @@ -1,2 +1,68 @@ * **练习16.1** +编译器使用实际的模板实参代替对应的模板参数来创建出模板的一个实例。 +* **练习16.2** +[16.2 程序代码](16.2.cpp) + +* **练习16.3** +Sales_data类 书上的版本 +测试错误信息 仅本题使用 +[16.3 Sales_data.h程序代码](16.3/Sales_data.h) +[16.3 Sales_data.cpp程序代码](16.3/Sales_data.cpp) +[16.3 测试程序代码](16.3/main.cpp) +错误信息为: +``` +error C2678: 二进制“<”: 没有找到接受“const Sales_data”类型的左操作数的运算符(或没有可 接受的转换) +note: 可能是“内置 C++ operator<(double, double)” +note: 尝试匹配参数列表“(const Sales_data, const Sales_data)”时 +note: 参见对正在编译的函数 模板 实例化“int compare(const T &,const T &)”的 引用 + with + [ + T=Sales_data + ] +error C2678: 二进制“<”: 没有找到接受“const Sales_data”类型的左操作数的运算符(或没有可 接受的转换) +note: 可能是“内置 C++ operator<(double, double)” +note: 尝试匹配参数列表“(const Sales_data, const Sales_data)”时 +``` + +* **练习16.4** +[16.4 程序代码](16.4.cpp) + +* **练习16.5** +[16.5 程序代码](16.5.cpp) + +* **练习16.6** +[16.6 程序代码](16.6.cpp) + +* **练习16.7** +[16.7 程序代码](16.7.cpp) + +* **练习16.8** +因为!=仅需要判断对象是否相等,而<需要判断对象的大小关系,相等关系相对更容易定义,适用范围更广 + +* **练习16.9** +函数模板是用来生成针对不同类型的函数的模板。 +类模板是用来生成针对不同类型的类的模板。 + +* **练习16.10** +类模板被实例化时生成针对特定类型的类。 + +* **练习16.11** +修改: +``` +template class ListItem; +template +class List +{ +public: + List(); + List(const List &); + List & operator=(const List &); + ~List(); + void insert(ListItem *ptr, elemType value); +private: + ListItem * front, * end; +}; +``` + +* **练习16.12**