您的位置:首页 > 编程语言 > C语言/C++

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

2015-09-15 12:15 369 查看
习题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;
}
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: