c++ primer 学习笔记-第十四章

来源:互联网 发布:英伦对决影评知乎 编辑:程序博客网 时间:2024/04/30 18:20

习题14.2:

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;}elsethrow 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;}elsethrow 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,进入elsetotal.combine(trans);else{out << total << endl;//这样写可以保证最后一条数据正常显示total = trans;}}out << total << endl;}else{cout << "特么的啥也没有?" << endl;}}elsecout << "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#endifclass 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 functionsostream &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;elsereturn 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[n];}const char &String::operator[](std::size_t n)const{return element[n];}

习题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;elsestd::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; }};//命名的lambdaauto 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


0 0
原创粉丝点击