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

习题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[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;
	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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值