練習7.1 使用2.6.1節定義的Sales_data類爲1.6節的交易處理程序編寫一個新版本。
解:
#include <iostream>
#include <string>
using std::cin; using std::cout; using std::endl; using std::string;
struct Sales_data
{
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
int main()
{
Sales_data total;
if (cin >> total.bookNo >> total.units_sold >> total.revenue)
{
Sales_data trans;
while (cin >> trans.bookNo >> trans.units_sold >> trans.revenue)
{
if (total.bookNo == trans.bookNo)
{
total.units_sold += trans.units_sold;
total.revenue += trans.revenue;
}
else
{
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;
total = trans;
}
}
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;
}
else
{
std::cerr << "No data?!" << std::endl;
return -1;
}
return 0;
}
練習7.2 曾在2.6.2節的練習中編寫了一個Sales_data類,請向這個類添加combine函數和isbn成員。
解:
#include <string>
struct Sales_data {
std::string isbn() const { return bookNo; };
Sales_data& combine(const Sales_data&);
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
練習7.3 修改7.1.1節的交易處理程序,令其使用這些成員。
解:
#include <iostream>
using std::cin; using std::cout; using std::endl;
int main()
{
Sales_data total;
if (cin >> total.bookNo >> total.units_sold >> total.revenue)
{
Sales_data trans;
while (cin >> trans.bookNo >> trans.units_sold >> trans.revenue) {
if (total.isbn() == trans.isbn())
total.combine(trans);
else {
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;
total = trans;
}
}
cout << total.bookNo << " " << total.units_sold << " " << total.revenue << endl;
}
else
{
std::cerr << "No data?!" << std::endl;
return -1;
}
return 0;
}
練習7.4 編寫一個名爲Person的類,使其表示人員的姓名和地址。使用string對象存放這些元素,接下來的練習將不斷充實這個類的其他特徵。
解:
#include <string>
class Person {
std::string name;
std::string address;
};
練習7.5 在你的Person類中提供一些操作使其能夠返回姓名和地址。 這些函數是否應該是const的呢?解釋原因。
解:
#include <string>
class Person
{
std::string name;
std::string address;
public:
auto get_name() const -> std::string const& { return name; }
auto get_addr() const -> std::string const& { return address; }
};
應該是const的。因爲常量的Person對象也需要使用這些函數操作。
練習7.6 對於函數add、read和print,定義你自己的版本。
解:
#include <string>
#include <iostream>
struct Sales_data {
std::string const& isbn() const { return bookNo; };
Sales_data& combine(const Sales_data&);
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
// member functions.
Sales_data& Sales_data::combine(const Sales_data& rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
// nonmember functions
std::istream &read(std::istream &is, Sales_data &item)
{
double price = 0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
std::ostream &print(std::ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue;
return os;
}
Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;
sum.combine(rhs);
return sum;
}
練習7.7 使用這些新函數重寫7.1.2節練習中的程序
int main()
{
Sales_data total;
if (read(std::cin, total))
{
Sales_data trans;
while (read(std::cin, trans)) {
if (total.isbn() == trans.isbn())
total.combine(trans);
else {
print(std::cout, total) << std::endl;
total = trans;
}
}
print(std::cout, total) << std::endl;
}
else
{
std::cerr << "No data?!" << std::endl;
return -1;
}
return 0;
}
練習7.8 爲什麼read函數將其Sales_data參數定義成普通的引用,而print函數將其參數定義成常量引用?
解: 因爲read函數會改變對象的內容,而print函數不會。
練習7.9 對於7.1.2節練習中代碼,添加讀取和打印Person對象的操作。
#include <string>
#include <iostream>
struct Person
{
std::string const& getName() const { return name; }
std::string const& getAddress() const { return address; }
std::string name;
std::string address;
};
std::istream &read(std::istream &is, Person &person)
{
return is >> person.name >> person.address;
}
std::ostream &print(std::ostream &os, const Person &person)
{
return os << person.name << " " << person.address;
}
練習7.10 在下面這條if語句中,條件部分的作用是什麼?
if (read(read(cin, data1), data2)) //等價read(std::cin, data1);read(std::cin, data2);
read函數的返回值是istream對象, if語句中條件部分的作用是從輸入流中讀取數據給兩個data對象。