本章習題大多相互承接,最終實現一個比較完整地類,鑑於這樣的特點,這裏不再貼出每一個練習的代碼,而是挑選幾個類列出其最終實現:
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");
}