c++ primer 学习笔记-第十四章
2015-09-15 12:15
369 查看
习题14.2:
Sales_data.h:
Sales_data.cpp:
main:
习题14.7:
String.h:
String.cpp:
main.cpp:
习题14.16:
习题14.18:
习题14.23:
习题14.26:
习题14.35:
习题14.36:
习题14.37:
.h
.cpp
习题14.38:
习题14.39:
习题14.43:
习题14.44:
Sales_data.h:
#ifndef SALES_DATA_H #define SALES_DATA_H #include <iostream> #include <fstream> #include <string> using std::string; using std::cin; using std::cout; using std::endl; using std::istream; using std::ostream; using std::ifstream; using std::ofstream; //为了在类内定义第四个构造函数所进行的声明 class Sales_data; istream &operator>>(istream &, Sales_data &); //类 class Sales_data { friend istream &operator>>(istream &is, Sales_data &item); friend ostream &operator<<(ostream &os, const Sales_data &item); friend Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs); public: //公有成员函数 string isbn()const; Sales_data &combine(const Sales_data &); //构造函数 explicit Sales_data(const string &s, unsigned int n, double p) :bookIsbn(s), units_sold(n), revenue(p*n){} Sales_data() :Sales_data("", 0, 0){}//默认构造函数 委托构造函数 Sales_data(const string &s) :Sales_data(s, 0, 0){ } Sales_data(istream &is) :Sales_data(){ is >> *this; } //+=运算符重载 Sales_data &operator+=(const Sales_data &); private: //成员变量 string bookIsbn; unsigned units_sold = 0; double revenue = 0.0; //私有成员函数 double avg_price()const; }; //<<、>>、+运算符重载 Sales_data operator+(const Sales_data &, const Sales_data &); istream &operator>>(istream &, Sales_data &); ostream &operator<<(ostream &, const Sales_data &); #endif
Sales_data.cpp:
#include <stdexcept>//使用runtime_error #include "Sales_data.h" using std::runtime_error; //类外定义的构造函数 //成员函数 string Sales_data::isbn()const { return bookIsbn; } Sales_data & Sales_data::combine(const Sales_data &rhs) { units_sold += rhs.units_sold; revenue += rhs.revenue; return *this; } double Sales_data::avg_price()const { return units_sold ? revenue / units_sold : 0; } //非成员函数 Sales_data &Sales_data::operator+=(const Sales_data &rhs) { while (true) { try{ if (this->isbn() == rhs.isbn()) { this->combine(rhs); return *this; } else throw runtime_error("输入的ISBN不相同,不能相加!"); } catch (runtime_error err){ cout << err.what() << endl << "Oops, try again? Enter Y/N." << endl; char c; cin >> c; if (!cin || tolower(c) == 'n') break; } } cout << "输入不正确,接下来的结果不予保证!" << endl; return Sales_data();//返回一个空对象 } Sales_data operator+(const Sales_data &lhs, const Sales_data &rhs) { Sales_data sum = lhs; while (true) { try{ if (lhs.isbn() == rhs.isbn()) { sum.combine(rhs); return sum; } else throw runtime_error("输入的ISBN不相同,不能相加!"); } catch (runtime_error err){ cout << err.what() << endl << "Oops, try again? Enter Y/N." << endl; char c; cin >> c; if (!cin || tolower(c) == 'n') break; } } cout << "输入不正确,接下来的结果不予保证!" << endl; return sum;//到这里应该只是随意返回一个错误对象了 } istream &operator>>(istream &is, Sales_data &item) { //cout << "请输入ISBN、已售数目、书本单价:" << endl; //cout << "read() called." << endl; double price = 0; is >> item.bookIsbn >> item.units_sold >> price; item.revenue = item.units_sold*price; return is; } ostream &operator<<(ostream &os, const Sales_data &item) { os << "ISBN编号:" << item.isbn() << " 已售出:" << item.units_sold << "本 平均价格:" << item.revenue / item.units_sold << "元 总收益:" << item.revenue << "元"; return os; }
main:
#include "Sales_data.h" int main(){ cout << "this is a test:" << endl; string read_file = "售卖记录.txt", write_file = "统计结果.txt"; ifstream in(read_file); ofstream out(write_file,ofstream::app); if (in && out) { cout << "Open file: " + read_file + " & " + write_file << endl; Sales_data total; if (in >> total) { Sales_data trans; while (in >> trans)//到最后一条时 此处不是输入数据的地方,cin返回true { if (total.isbn() == trans.isbn())//可在else下加入cout测得trans.bookIsbn为空,返回0,进入else total.combine(trans); else { out << total << endl;//这样写可以保证最后一条数据正常显示 total = trans; } } out << total << endl; } else { cout << "特么的啥也没有?" << endl; } } else cout << "Cannot open file:" + read_file + "&" + write_file << endl; getchar(); getchar(); return 0; }
习题14.7:
String.h:
#ifndef STRING_H #define STRING_H #include <iostream> #include <memory> #include <utility> #include <algorithm> using std::cout; using std::endl; using std::istream; using std::ostream; #ifndef _MSC_VER #define NOEXCEPT noexcept #else #define NOEXCEPT #endif class String { friend ostream &operator<<(ostream &, const String &); public: //移动构造函数&移动赋值运算符 String(String &&)NOEXCEPT; String &operator=(String &&)NOEXCEPT; //构造函数 String() :String(""){ cout << "默认拷贝构造函数" << endl; }; String(const char *); //拷贝构造函数 String(const String &); //拷贝赋值运算符 String &operator=(const String &rhs); //析构函数 ~String(); std::size_t size(){ return first_free - element; } std::size_t capacity(){ return cap - element; } void push_back(const char &c); private: std::allocator<char> alloc; char *element; char *first_free; char *cap; std::pair<char *, char *> alloc_n_copy(const char *, const char *); void range_init(const char *, const char *); void check_n_alloc(); void free(); void reallocate(); }; //输出运算符 ostream &operator<<(ostream &, const String &); #endif
String.cpp:
#include "String.h" String::String(String &&rhs) NOEXCEPT :element(rhs.element), first_free(rhs.first_free), cap(rhs.cap) { cout << "移动构造函数" << endl; rhs.element = rhs.first_free = rhs.cap = nullptr; } String &String::operator=(String &&rhs)NOEXCEPT { cout << "移动赋值运算符" << endl; if (this != &rhs) { free(); element = rhs.element; first_free = rhs.first_free; cap = rhs.cap; rhs.element = rhs.first_free = rhs.cap = nullptr; } return *this; } void String::check_n_alloc() { //std::cout << "check_n_alloc~" << std::endl; if (size() == capacity()) reallocate(); } void String::push_back(const char &c) { //std::cout << "push_back~" << std::endl; check_n_alloc(); alloc.construct(first_free++, c); } void String::reallocate() { //std::cout << "reallocate~" << std::endl; auto new_capacity = size() ? 2 * size() : 1; auto new_data = alloc.allocate(new_capacity); auto dest = new_data; auto elem = element; for (size_t i = 0; i != size(); ++i) alloc.construct(dest++, std::move(*elem++)); free(); element = new_data; cap = first_free = element + new_capacity; } std::pair<char *, char *> String::alloc_n_copy(const char *beg, const char *end) { //std::cout << "alloc_n_copy~" << std::endl; auto new_beg = alloc.allocate(end - beg); return{ new_beg, std::uninitialized_copy(beg, end, new_beg) }; } void String::range_init(const char *beg, const char *end) { //std::cout << "range_init~" << std::endl; auto new_data = alloc_n_copy(beg, end); element = new_data.first; first_free = new_data.second; } String::String(const char *pc_beg) { std::cout << "C风格字符串构造函数调用~" << std::endl; auto pc_end = const_cast<char*>(pc_beg); while (*pc_end) ++pc_end; range_init(pc_beg, ++pc_end); } String::String(const String &rhs) { std::cout << "拷贝构造函数调用~" << std::endl; range_init(rhs.element, rhs.first_free); } String &String::operator=(const String &rhs) { std::cout << "赋值运算符调用~" << std::endl; auto data = alloc.allocate(rhs.first_free - rhs.element); free(); element = rhs.element; first_free = rhs.first_free; return *this; } void String::free() { std::cout << "free~" << std::endl; if (element) std::for_each(element, first_free, [this](const char &c){alloc.destroy(&c); }); alloc.deallocate(element, first_free - element); element = first_free = nullptr; } String::~String() { free(); } //overloaded operator functions ostream &operator<<(ostream &os, const String &s) { for (auto beg = s.element; beg != s.first_free; ++beg) os << *beg; return os; }
main.cpp:
#include "String.h" #include <vector> String func() { String ret("a"); return ret; } int main() { //String s = func(); String ss( "hello" ); cout << ss << endl; getchar(); return 0; }
习题14.16:
//运算符重载 bool operator==(const StrVec &lhs, const StrVec &rhs) { return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin()); } bool operator!=(const StrVec &lhs, const StrVec &rhs) { return !(lhs == rhs); }begin() end()都是定义的有const限定符的成员函数,只是返回数据成员,即那几个指针。
习题14.18:
bool operator<(const StrVec &lhs, const StrVec &rhs) { auto lp = lhs.begin(), rp = rhs.begin(); while (lp != lhs.end() && rp != rhs.end()) { if (*lp < *rp) return true; else if (*lp>*rp) return false; ++lp, ++rp; } if (lp == lhs.end() && rp!=rhs.end()) return true; else return false; } bool operator<=(const StrVec &lhs, const StrVec &rhs) { return !(rhs < lhs); } bool operator>(const StrVec &lhs, const StrVec &rhs) { return rhs < lhs; } bool operator>=(const StrVec &lhs, const StrVec &rhs) { return !(lhs < rhs); }
习题14.23:
StrVec &StrVec::operator=(std::initializer_list<std::string> slst)//构造函数已经有了就用啊 { *this = StrVec(slst); return *this; }
习题14.26:
char &String::operator[](std::size_t n) { return element ; } const char &String::operator[](std::size_t n)const { return element ; }
习题14.35:
#ifndef PRINTPAINT_H #define PRINTPAINT_H #include <iostream> #include <string> using std::cin; using std::string; using std::istream; class GetInput { public: GetInput(std::istream &i = std::cin) :is(i){ } string operator()()const { string s; getline(is, s); return is ? s : string(); } private: istream &is;//注意这里一定是引用 }; #endif
习题14.36:
#include "标头.h" #include <vector> int main() { std::vector<string> givec; GetInput gi; for (string temp; !(temp = gi()).empty(); givec.push_back(temp)); for (auto g : givec) std::cout << g << " "; std::cout << std::endl; getchar(); return 0; }
习题14.37:
.h
#ifndef PRINTPAINT_H #define PRINTPAINT_H #include <iostream> #include <string> using std::cin; using std::string; using std::istream; class Equal { public: Equal(const int &ii) :i(ii){ }; bool operator()(const int &i2)const { return i == i2; } private: int i; }; #endif
.cpp
#include "标头.h" #include <vector> #include <algorithm> using std::vector; int main() { vector<int> ivec{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 5, 2, 4, 6, 1, 3 }; //Equal eq(5); //for (auto beg = ivec.begin(); //(beg = std::find_if(beg, ivec.end(), eq)) != ivec.end(); //*beg = 42); std::replace_if(ivec.begin(), ivec.end(), Equal(5), 42); for (auto i : ivec) std::cout << i << " "; std::cout << std::endl; getchar(); return 0; }
习题14.38:
#ifndef PRINTPAINT_H #define PRINTPAINT_H #include <iostream> #include <string> using std::cin; using std::string; using std::istream; class Count { public: Count(std::size_t t) :n(t){ }; bool operator()(const string &s) { return s.size() == n; } private: std::size_t n; }; #endif
#include "标头.h" #include <vector> #include <iterator> #include <algorithm> #include <fstream> using std::vector; int main() { std::ifstream file("有标点单词段落测试.txt"); vector<string> svec; string s_temp; while (file >> s_temp) { string s_org; std::remove_copy_if(s_temp.begin(), s_temp.end(), std::back_inserter(s_org), ispunct); svec.push_back(s_org); std::cout << s_org << std::endl; } vector<int> ivec; for (std::size_t i = 0; i != 10; ++i) ivec.push_back(std::count_if(svec.begin(), svec.end(), Count(i + 1))); for (auto i : ivec) std::cout << i << " "; std::cout << std::endl; getchar(); return 0; }
习题14.39:
#ifndef PRINTPAINT_H #define PRINTPAINT_H #include <iostream> #include <string> using std::cin; using std::string; using std::istream; class Count { public: Count(std::size_t low, std::size_t high) :_low(low), _high(high){ }; bool operator()(const string &s) { return s.size() >= _low && s.size() <= _high; } private: std::size_t _low; std::size_t _high; }; #endif
#include "标头.h" #include <vector> #include <iterator> #include <algorithm> #include <fstream> using std::vector; int main() { std::ifstream file("有标点单词段落测试.txt"); vector<string> svec; string s_temp; while (file >> s_temp) { string s_org; std::remove_copy_if(s_temp.begin(), s_temp.end(), std::back_inserter(s_org), ispunct); svec.push_back(s_org); std::cout << s_org << std::endl; } vector<int> ivec; ivec.push_back(std::count_if(svec.begin(), svec.end(), Count(1, 9))); ivec.push_back(std::count_if(svec.begin(), svec.end(), Count(10, 100))); for (auto i : ivec) std::cout << i << " "; std::cout << std::endl; getchar(); return 0; }
习题14.43:
int n; cin >> n; vector<int> ivec{ 2, 3, 5 }; std::modulus<int> mod; auto predicate = [&](const int i){return 0 != mod(n, i); }; auto iter = std::find_if(ivec.begin(), ivec.end(), predicate); if (iter == ivec.end()) std::cout << "true" << std::endl; else std::cout << "false" << std::endl;
习题14.44:
#ifndef CALCULATOR_H #define CALCULATOR_H #include <iostream> #include <functional> #include <map> #include <string> #include <algorithm> //普通函数 int multiply(int i, int j){ return i*j; } //函数对象类 struct mod{ int operator()(int i, int j){ return i%j; } }; //命名的lambda auto devide = [](int i, int j){return i / j; }; // std::map<std::string, std::function<int(int, int)>> binops = { { "+", [](int i, int j){return i + j; } },//未命名lambda { "-", std::minus<int>() },//标准库函数对象 { "*", multiply }, { "%",mod()}, { "/",devide } }; int calc(std::string &calc_operator, int lhs, int rhs) { return binops[calc_operator](lhs, rhs); } void arrange_calc()//其实顺序读入变量就好了 我这搞得还分离了一下字符串 傻了 { std::string input; std::string calc_operator; std::string lhs_s, rhs_s; std::cout << ">>"; while (std::cin >> input && input[0]!='q') { auto op = std::find_if_not(input.begin(), input.end(), isalnum); auto iter = std::find_if(op, input.end(), isalnum); std::copy(input.begin(), op, std::back_inserter(lhs_s)); std::copy(op, iter, std::back_inserter(calc_operator)); std::copy(iter, input.end(), std::back_inserter(rhs_s)); std::cout << calc(calc_operator, atoi(lhs_s.c_str()), atoi(rhs_s.c_str())) << std::endl; std::cout << ">>"; lhs_s.clear(); rhs_s.clear(); calc_operator.clear(); } } #endif
相关文章推荐
- C++ 预定义显示文件和行数的调试技术
- c++中抽象类与接口的区别
- 使用C语言操作MySQL数据库
- 如何在C++代码中遍历QML Item并修改它的属性
- Effective C++——条款37(第6章)
- C++ 'dynamic_cast' and Java 'instanceof' 使用对比
- Item 27:最小化类型转换 Effective C++笔记
- C语言不定长参数的实现 va_list
- C++11
- Effective C++ ——规则1-3
- c语言--二维数组的首地址问题
- C++ 拷贝构造函数 赋值构造函数
- OC语言中的block数据类型
- C++微专业课程辅导(内存模型和动态内存)
- 【C++】二叉树的创建方法及其遍历的递归与非递归方法总结
- 【第3周 项目2 - 建设“顺序表”算法库】
- C++Primer第五版 6.5.1节练习
- C++Primer第五版 6.4节练习
- C++模板
- C++Primer第五版 6.3.3节练习