C++ Primer習題解答 Chapter7

本章習題大多相互承接,最終實現一個比較完整地類,鑑於這樣的特點,這裏不再貼出每一個練習的代碼,而是挑選幾個類列出其最終實現:

1.Sales_data類

//Sales_data.h
#include<string>

using namespace std;

class Sales_data;
//友元函數的類外聲明
istream& read(istream &in, Sales_data &item);
Sales_data add(const Sales_data &item1, const Sales_data &item2);
ostream& print(ostream &out, const Sales_data &item);

class Sales_data
{
	friend istream& read(istream &in, Sales_data &item);
	friend Sales_data add(const Sales_data &item1, const Sales_data &item2);
	friend ostream& print(ostream &out, const Sales_data &item);
private://類實現
	string bookNo;
	unsigned int units_sold = 0;
	double revenue = 0.0;
public://類接口
	Sales_data& combine(const Sales_data &item);
	//類內實現的函數可以隱式內聯,inline關鍵字可以省略
	inline string isbn() const { return bookNo; };
	inline double avg_price() { return revenue / units_sold; };
	Sales_data() = default;
	Sales_data(string isbn) :bookNo(isbn) {}
	Sales_data(istream &in);
	Sales_data(string isbn, int units, double price) :
		bookNo(isbn), units_sold(units), revenue(price*units) {}
};

//Sales_data.cpp
#include"Sales_data.h"


Sales_data::Sales_data(istream &in)
{
	read(in, *this);
}

Sales_data& Sales_data::combine(const Sales_data &item)
{
	units_sold += item.units_sold;
	revenue += item.revenue;
	return *this;
}
istream& read(istream &in, Sales_data &item)
{
	double price;
	in >> item.bookNo >> item.units_sold >> price;
	item.revenue = item.units_sold * price;
	return in;
}

Sales_data add(const Sales_data &item1, const Sales_data &item2)
{
	Sales_data item;
	item.bookNo = item1.bookNo;
	item.units_sold = item1.units_sold + item2.units_sold;
	item.revenue = item1.revenue + item2.revenue;
	return item;
}

ostream& print(ostream &out, const Sales_data &item)
{
	out << item.bookNo << " " << item.units_sold << " " << item.revenue;
	return out;
}

//main.cpp
#include<iostream>
#include<vector>
#include<string>
#include<cctype>
#include<iterator>
#include<stdexcept>
#include"Sales_data.h"


int main()
{
	Sales_data total;
	cout << "輸入訂單信息(ISBN,數量,價錢):" << endl;
	read(cin, total);
	Sales_data item;
	cout << "輸入訂單信息(ISBN,數量,價錢):" << endl;
	while (read(cin, item)) {
		if (item.isbn() == total.isbn()) {
			total.combine(item);
			//total = add(total, item);
		}
		else {
			cout << "order information:" << endl;
			print(cout, total) << endl;
			total = item;
		}
		cout << "輸入訂單信息(ISBN,數量,價錢):" << endl;
	}
	print(cout, total);
	system("pause");
}

2.Screen類和Winodw_mgr類

//Window_mgr.h
#pragma once

#include<vector>
#include<iostream>

using namespace std;

class Screen;

//先聲明作爲另一個類的友元的成員函數,不要定義
class Window_mgr
{
private:
	//screens是一個screen的向量
	vector<Screen> screens;
public:
	void clear(unsigned i);
};



//Screen.h
#pragma once

#include<string>
#include<iostream>
#include"Window_mgr.h"

using namespace std;

//聲明另一個類,這個類聲明某其他類成員函數是自己的友元
class Screen
{
	string contents;
	unsigned int height = 0, width = 0;
	unsigned cursor = 0;
private:
	void do_display(ostream &out) const
	{
		out << contents;
	}
public:
	Screen() = default;
	Screen(unsigned int ht, unsigned int wd) :
		height(ht), width(wd) {}
	Screen(unsigned int ht, unsigned int wd, char c) :
		height(ht), width(wd), contents(ht*wd, c) {};
	//移動光標
	Screen& move(unsigned r, unsigned c);
	//設置光標位置字符
	Screen& set(char ch);
	//設置指定位置字符
	Screen& set(unsigned r, unsigned c, char ch);
	/*
	 *理論上來說display並沒有改變對象,可以使const的
	 *但是這樣會導致返回*this總是得到const對象,沒法進一步調用非常量成員函數
	 *所以重載之
	 */
	const Screen& display(ostream &out) const;
	Screen& display(ostream &out);

	friend void Window_mgr::clear(unsigned i);
};



//Screen.cpp
#include"Screen.h"

Screen& Screen::move(unsigned r, unsigned c)
{
	cursor = width * r + c;
	return *this;
}

Screen& Screen::set(char ch)
{
	contents[cursor] = ch;
	return *this;
}
//r,c是行號和列號,從零開始,不是序數
Screen& Screen::set(unsigned r, unsigned c, char ch)
{
	contents[r*width + c] = ch;
	return *this;
}

const Screen& Screen::display(ostream &out) const
{
	do_display(out);
	out << contents;
	return *this;
}

Screen& Screen::display(ostream &out)
{
	do_display(out);
	return *this;
}



//Window_mgr.cpp
#pragma once
#include"Window_mgr.h"

#include"Screen.h"


//友元函數定義
void Window_mgr::clear(unsigned i)
{
	screens.push_back(Screen(24, 80, '#'));
	Screen myScreen = screens[i];
	cout << "清空前" << endl;
	myScreen.display(cout);
	myScreen.contents = string(myScreen.height*myScreen.width, ' ');
	cout << "清空後" << endl;
	myScreen.display(cout);
}



//main.cpp
#include<iostream>
#include<vector>
#include<string>
#include<cctype>
#include<iterator>
#include<stdexcept>
#include"Sales_data.h"


int main()
{
	Sales_data total;
	cout << "輸入訂單信息(ISBN,數量,價錢):" << endl;
	read(cin, total);
	Sales_data item;
	cout << "輸入訂單信息(ISBN,數量,價錢):" << endl;
	while (read(cin, item)) {
		if (item.isbn() == total.isbn()) {
			total.combine(item);
			//total = add(total, item);
		}
		else {
			cout << "order information:" << endl;
			print(cout, total) << endl;
			total = item;
		}
		cout << "輸入訂單信息(ISBN,數量,價錢):" << endl;
	}
	print(cout, total);
	system("pause");
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章