本章习题大多相互承接,最终实现一个比较完整地类,鉴于这样的特点,这里不再贴出每一个练习的代码,而是挑选几个类列出其最终实现:
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");
}