練習7.1
/******************************************************************************
* 使用2.6.1節聯系定義的Sales_data類為1.6節(第21頁)的交易處理程式編寫一個新版本。
*****************************************************************************/
#include <iostream>
struct Sales_data
{
std::string isbn;
double price = 0.0;
unsigned quantity = 0;
double revenue = 0.0;
};
int main()
{
Sales_data total; // 儲存下一條交易記錄的變量
//讀入第一條交易記錄,并確定有資料可以處理
if (std::cin >> total.isbn >> total.price >> total.quantity)
{
total.revenue = total.price * total.quantity;
Sales_data trans; //儲存和的變量
//讀入并處理剩餘交易記錄
while (std::cin >> trans.isbn >> trans.price >> trans.quantity)
{
trans.revenue = trans.price * trans.quantity;
//如果我們仍在處理相同的書
if (total.isbn == trans.isbn)
total.revenue += trans.revenue; //更新總銷售額
else
{
//列印前一本書的結果
std::cout << "ISBN:" << total.isbn << "\n單價:" << total.revenue / double(total.quantity) << "\n數量:" << total.quantity << "\n總銷售額:" << total.revenue << std::endl;
//total現在表示下一本書的銷售額
total.isbn = trans.isbn;
total.price = trans.price;
total.quantity = trans.quantity;
total.revenue = trans.revenue;
}
}
std::cout << "ISBN:" << total.isbn << "\n單價:" << total.revenue / double(total.quantity) << "\n數量:" << total.quantity << "\n總銷售額:" << total.revenue << std::endl;
}
else
{
//沒有輸入!警告讀者
std::cerr << "No data?!" << std::endl;
return -1; //表示失敗
}
return 0;
}
練習7.2
/******************************************************************************
* 曾在2.6.2節的練習(第67頁)中編寫了一個Sales_data類,請向這個類添加combine和isbn
* 成員。
*****************************************************************************/
#include <iostream>
struct Sales_data
{
std::string isbn() const { return bookNo; }
Sales_data &combine(const Sales_data &);
std::string bookNo;
double price = 0.0;
unsigned quantity = 0;
double revenue = 0;
};
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
price += rhs.price;
revenue += rhs.revenue;
return *this;
}
int main()
{
Sales_data book;
std::cin >> book.bookNo >> book.quantity >> book.price; //讀入ISBN号、售出的冊數以及銷售價格
double total_sales = book.quantity * book.price;
double average_price = 0.0;
if (book.quantity != 0)
{
average_price = total_sales / book.quantity;
std::cout << book.bookNo << " " << book.quantity << " " << total_sales << " " << average_price << std::endl; //寫入ISBN号、銷售總額以及平均價格
}
else
std::cout << "售出冊數為0" << std::endl;
//以下為Sales_data的兩個對象的相加
Sales_data book1;
std::cin >> book1.bookNo >> book1.quantity >> book1.price; //寫入ISBN号、售出的冊數以及銷售價格
if (book1.bookNo == book.bookNo)
{
book.quantity += book1.quantity;
total_sales += book1.price * book1.quantity;
if (book.quantity != 0)
{
average_price = total_sales / book.quantity;
std::cout << book.bookNo << " " << book.quantity << " " << total_sales << " " << average_price << std::endl; //寫入ISBN号、銷售總額以及平均價格
}
else
std::cout << "售出冊數為0" << std::endl;
}
else
std::cout << "它們不是同一本書!" << std::endl;
return 0;
}
練習7.3
/******************************************************************************
* 修改7.1.1節(第229頁)的交易處理程式,令其使用這些成員。
*****************************************************************************/
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
struct Sales_data
{
//新成員:關于Sales_data對象的操作
std::string isbn() const { return bookNo; }
Sales_data &combine(const Sales_data &);
double avg_price() const;
//資料成員和2.6.1節(第64頁)相比沒有改變
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
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()) //檢查isbn
total.combine(trans); //更新變量total目前的值
else
{
cout << "ISBN:" << total.isbn() << "\n數量:" << total.units_sold << "\n均價:" << total.avg_price() << "\n總銷售額:" << total.revenue << endl; //輸出結果
total = trans; //處理下一本書
}
}
cout << "ISBN:" << total.isbn() << "\n數量:" << total.units_sold << "\n均價:" << total.avg_price() << "\n總銷售額:" << total.revenue << endl; //輸出最後一條交易
}
else //沒有輸入任何資訊
{
cerr << "No data?!" << endl;
}
}
練習7.4
/******************************************************************************
* 編寫一個名為Person的類,使其表示人員的姓名和住址。使用string對象存放這些元素,接下
* 來的練習将不斷充實這個類的其他特征。
*****************************************************************************/
#include <iostream>
using std::cout;
using std::endl;
using std::string;
struct Person
{
string name;
string address;
};
int main()
{
Person p;
p.name = "qw";
p.address = "er";
cout << "姓名:" << p.name << "\n位址:" << p.address << endl;
return 0;
}
練習7.5
/******************************************************************************
* 在你的Person類中提供一些操作使其能夠傳回姓名和住址。這些函數是否應該是const的呢?
* 解釋原因。
*****************************************************************************/
#include <iostream>
using std::cout;
using std::endl;
using std::string;
struct Person
{
string get_name() const { return name; }
string get_address() const { return address; }
string name;
string address;
};
int main()
{
Person p;
p.name = "qw";
p.address = "er";
cout << "姓名:" << p.get_name() << "\n位址:" << p.get_address() << endl;
return 0;
}
練習7.6
/******************************************************************************
* 對于函數add、read和print,定義你自己的版本。
*****************************************************************************/
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
struct Sales_data
{
//新成員:關于Sales_data對象的操作
std::string isbn() const { return bookNo; }
Sales_data &combine(const Sales_data &);
double avg_price() const;
//資料成員和2.6.1節(第64頁)相比沒有改變
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
Sales_data add(Sales_data lhs, const Sales_data rhs)
{
return lhs.combine(rhs);
}
istream &read(istream &is, Sales_data &item)
{
double price = 0.0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
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()) //檢查isbn
total.combine(trans); //更新變量total目前的值
else
{
cout << "ISBN:" << total.isbn() << "\n數量:" << total.units_sold << "\n均價:" << total.avg_price() << "\n總銷售額:" << total.revenue << endl; //輸出結果
total = trans; //處理下一本書
}
}
cout << "ISBN:" << total.isbn() << "\n數量:" << total.units_sold << "\n均價:" << total.avg_price() << "\n總銷售額:" << total.revenue << endl; //輸出最後一條交易
}
else //沒有輸入任何資訊
{
cerr << "No data?!" << endl;
}
}
練習7.7
/******************************************************************************
* 使用這些新函數重寫7.1.2節(第233頁)練習中的交易處理程式。
*****************************************************************************/
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
struct Sales_data
{
//新成員:關于Sales_data對象的操作
std::string isbn() const { return bookNo; }
Sales_data &combine(const Sales_data &);
double avg_price() const;
//資料成員和2.6.1節(第64頁)相比沒有改變
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
Sales_data add(Sales_data lhs, const Sales_data rhs)
{
return lhs.combine(rhs);
}
istream &read(istream &is, Sales_data &item)
{
double price = 0.0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
int main()
{
Sales_data total; //儲存目前求和結果的變量
if (read(cin, total)) //讀入第一筆交易
{
Sales_data trans; //儲存下一條交易資料的變量
while (read(cin, trans)) //讀取剩餘的交易
{
if (total.isbn() == trans.isbn()) //檢查isbn
total = add(total, trans); //更新變量total目前的值
else
{
print(cout, total) << endl; //輸出結果
total = trans; //處理下一本書
}
}
print(cout, total) << endl; //輸出最後一條交易
}
else //沒有輸入任何資訊
{
cerr << "No data?!" << endl;
}
}
練習7.9
/******************************************************************************
* 對于7.1.2節(第233頁)練習中的代碼,添加讀取和列印Person對象的操作。
*****************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
struct Person
{
string get_name() const { return name; }
string get_address() const { return address; }
string name;
string address;
};
istream &read(istream &is, Person &per)
{
is >> per.name >> per.address;
return is;
}
ostream &print(ostream &os, const Person &per)
{
os << per.get_name() << " " << per.get_address();
return os;
}
int main()
{
Person per;
read(cin, per);
print(cout, per) << endl;
return 0;
}
練習7.11
/******************************************************************************
* 在你的Sales_data類中添加構造函數,然後編寫一段程式令其用到每個構造函數。
*****************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
struct Sales_data
{
Sales_data() = default;
Sales_data(const string &b) : bookNo(b) {}
Sales_data(const string &b, unsigned u, double p) : bookNo(b), units_sold(u), revenue(p * u) {}
Sales_data(istream &);
//關于Sales_data對象的操作
std::string isbn() const { return bookNo; }
Sales_data &combine(const Sales_data &);
double avg_price() const;
//資料成員和2.6.1節(第64頁)相比沒有改變
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
Sales_data add(Sales_data lhs, const Sales_data rhs)
{
return lhs.combine(rhs);
}
istream &read(istream &is, Sales_data &item)
{
double price = 0.0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
Sales_data::Sales_data(istream &is)
{
read(is, *this);
}
int main()
{
Sales_data sd0;
print(cout, sd0) << endl;
Sales_data sd1("QWER");
print(cout, sd1) << endl;
Sales_data sd2("TYUI", 1, 2);
print(cout, sd2) << endl;
Sales_data sd3(cin);
print(cout, sd3) << endl;
}
練習7.12
/******************************************************************************
* 把隻接受一個istream作為參數的構造函數定義移到類的内部。
*****************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
struct Sales_data
{
Sales_data() = default;
Sales_data(const string &b) : bookNo(b) {}
Sales_data(const string &b, unsigned u, double p) : bookNo(b), units_sold(u), revenue(p * u) {}
Sales_data(istream &is) { read(is, *this); }
//關于Sales_data對象的操作
string isbn() const { return bookNo; }
Sales_data &combine(const Sales_data &);
double avg_price() const;
istream &read(istream &is, Sales_data &item);
//資料成員和2.6.1節(第64頁)相比沒有改變
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
Sales_data add(Sales_data lhs, const Sales_data rhs)
{
return lhs.combine(rhs);
}
istream &Sales_data::read(istream &is, Sales_data &item)
{
double price = 0.0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
int main()
{
Sales_data sd0;
print(cout, sd0) << endl;
Sales_data sd1("QWER");
print(cout, sd1) << endl;
Sales_data sd2("TYUI", 1, 2);
print(cout, sd2) << endl;
Sales_data sd3(cin);
print(cout, sd3) << endl;
}
練習7.13
/******************************************************************************
* 使用istream構造函數重寫第229頁的程式。
*****************************************************************************/
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
struct Sales_data
{
Sales_data() = default;
Sales_data(const string &b) : bookNo(b) {}
Sales_data(const string &b, unsigned u, double p) : bookNo(b), units_sold(u), revenue(p * u) {}
Sales_data(istream &is) { read(is, *this); }
//關于Sales_data對象的操作
string isbn() const { return bookNo; }
Sales_data &combine(const Sales_data &);
double avg_price() const;
istream &read(istream &is, Sales_data &item);
//資料成員和2.6.1節(第64頁)相比沒有改變
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
Sales_data add(Sales_data lhs, const Sales_data rhs)
{
return lhs.combine(rhs);
}
istream &Sales_data::read(istream &is, Sales_data &item)
{
double price = 0.0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
int main()
{
Sales_data total(cin);
if (total.isbn() != "")
{
while (true) //讀取剩餘的交易
{
Sales_data trans(cin);//儲存下一條交易資料的變量
if(trans.isbn()=="") break;
if (total.isbn() == trans.isbn()) //檢查isbn
total = add(total, trans); //更新變量total目前的值
else
{
print(cout, total) << endl; //輸出結果
total = trans; //處理下一本書
}
}
print(cout, total) << endl; //輸出最後一條交易
}
else //沒有輸入任何資訊
{
cerr << "No data?!" << endl;
}
}
練習7.14
/******************************************************************************
* 編寫一個構造函數,令其使用我們提供的類内初始值顯式地初始化成員。
*****************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
struct Sales_data
{
Sales_data() {}
//關于Sales_data對象的操作
string isbn() const { return bookNo; }
Sales_data &combine(const Sales_data &);
double avg_price() const;
istream &read(istream &is, Sales_data &item);
//資料成員和2.6.1節(第64頁)相比沒有改變
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
Sales_data add(Sales_data lhs, const Sales_data rhs)
{
return lhs.combine(rhs);
}
istream &Sales_data::read(istream &is, Sales_data &item)
{
double price = 0.0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
int main()
{
Sales_data sd0;
print(cout, sd0) << endl;
}
練習7.15
/******************************************************************************
* 為你的Person類添加正确的構造函數。
*****************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
struct Person
{
Person() = default;
Person(const string &n) : name(n) {}
Person(const string &n, const string &a) : name(n), address(a) {}
Person(istream &);
string get_name() const { return name; }
string get_address() const { return address; }
string name;
string address;
};
istream &read(istream &is, Person &per)
{
is >> per.name >> per.address;
return is;
}
ostream &print(ostream &os, const Person &per)
{
os << per.get_name() << " " << per.get_address();
return os;
}
Person::Person(istream &is)
{
read(is, *this);
}
int main()
{
Person per0;
print(cout, per0) << endl;
Person per1("qwer");
print(cout, per1) << endl;
Person per2("qwer", "tyui");
print(cout, per2) << endl;
Person per3(cin);
print(cout, per3);
return 0;
}
練習7.21
/******************************************************************************
* 修改你的Sales_data類使其隐藏實作的細節。你之前編寫的關于Sales_data操作的程式應該
* 繼續使用,借助類的新定義重新編譯該程式,確定其工作正常。
*****************************************************************************/
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
class Sales_data
{
friend Sales_data add(Sales_data, const Sales_data);
friend ostream &print(ostream &, const Sales_data &);
public:
Sales_data() = default;
Sales_data(const string &b) : bookNo(b) {}
Sales_data(const string &b, unsigned u, double p) : bookNo(b), units_sold(u), revenue(p * u) {}
Sales_data(istream &is) { read(is, *this); }
//關于Sales_data對象的操作
string isbn() const { return bookNo; }
istream &read(istream &is, Sales_data &item);
private:
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
double avg_price() const;
Sales_data &combine(const Sales_data &);
};
double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
Sales_data add(Sales_data lhs, const Sales_data rhs)
{
return lhs.combine(rhs);
}
istream &Sales_data::read(istream &is, Sales_data &item)
{
double price = 0.0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
int main()
{
Sales_data total(cin);
if (total.isbn() != "")
{
while (true) //讀取剩餘的交易
{
Sales_data trans(cin); //儲存下一條交易資料的變量
if (trans.isbn() == "")
break;
if (total.isbn() == trans.isbn()) //檢查isbn
total = add(total, trans); //更新變量total目前的值
else
{
print(cout, total) << endl; //輸出結果
total = trans; //處理下一本書
}
}
print(cout, total) << endl; //輸出最後一條交易
}
else //沒有輸入任何資訊
{
cerr << "No data?!" << endl;
}
}
練習7.22
/******************************************************************************
* 修改你的Person類使其隐藏實作的細節。
*****************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
struct Person
{
friend istream &read(istream &is, Person &per);
public:
Person() = default;
Person(const string &n) : name(n) {}
Person(const string &n, const string &a) : name(n), address(a) {}
Person(istream &);
string get_name() const { return name; }
string get_address() const { return address; }
private:
string name;
string address;
};
istream &read(istream &is, Person &per)
{
is >> per.name >> per.address;
return is;
}
ostream &print(ostream &os, const Person &per)
{
os << per.get_name() << " " << per.get_address();
return os;
}
Person::Person(istream &is)
{
read(is, *this);
}
int main()
{
Person per0;
print(cout, per0) << endl;
Person per1("qwer");
print(cout, per1) << endl;
Person per2("qwer", "tyui");
print(cout, per2) << endl;
Person per3(cin);
print(cout, per3);
return 0;
}
練習7.23
/******************************************************************************
* 編寫你自己的Screen類。
*****************************************************************************/
#include <iostream>
using std::cout;
using std::endl;
using std::string;
class Screen
{
public:
using pos = string::size_type;
Screen() = default;
Screen(pos w) : width(w) {}
Screen(pos w, pos h) : width(w), height(h) {}
Screen(pos w, pos h, pos c) : width(w), height(h), cursor(c) {}
Screen(pos w, pos h, pos c, char s) : width(w), height(h), cursor(c), contents(h * w, s) {}
char get() const { return contents[cursor]; }
char get(pos, pos) const;
Screen &move(pos, pos);
private:
pos cursor = 0, width = 0, height = 0;
string contents;
};
char Screen::get(pos x, pos y) const
{
pos row = x * width;
return contents[row + y];
}
Screen &Screen::move(pos r, pos c)
{
pos row = r * width;
cursor = row + c;
return *this;
}
int main()
{
Screen s0(10, 10, 20, 'a');
char a = s0.get();
cout << a << "\n";
s0.move(3, 4);
a = s0.get(3, 4);
cout << a << endl;
return 0;
}
練習7.24
/******************************************************************************
* 給你的Screen類添加三個構造函數:一個預設構造函數;另一個構造函數接受寬和高,然後将
* content初始化成給定數量的空白;第三個構造函數接受寬和高的值以及一個字元,該字元作
* 為初始化之後螢幕的内容。
*****************************************************************************/
#include <iostream>
using std::cout;
using std::endl;
using std::string;
class Screen
{
public:
using pos = string::size_type;
Screen() = default;
Screen(pos w, pos h) : width(w), height(h), contents(w * h, ' ') {}
Screen(pos w, pos h, char s) : width(w), height(h), contents(h * w, s) {}
char get() const { return contents[cursor]; }
char get(pos, pos) const;
Screen &move(pos, pos);
private:
pos cursor = 0, width = 0, height = 0;
string contents;
};
char Screen::get(pos x, pos y) const
{
pos row = x * width;
return contents[row + y];
}
Screen &Screen::move(pos r, pos c)
{
pos row = r * width;
cursor = row + c;
return *this;
}
int main()
{
Screen s0(10, 10), s1(10, 10, 's');
for (unsigned i = 0; i != 10; ++i)
{
for (unsigned j = 0; j != 10; ++j)
cout << s0.get(i, j);
cout << endl;
}
for (unsigned i = 0; i != 10; ++i)
{
for (unsigned j = 0; j != 10; ++j)
cout << s1.get(i, j);
cout << endl;
}
return 0;
}
練習7.26
/******************************************************************************
* 将Sales_data::avg_price定義成内聯函數。
*****************************************************************************/
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
class Sales_data
{
friend Sales_data add(Sales_data, const Sales_data);
friend ostream &print(ostream &, const Sales_data &);
public:
Sales_data() = default;
Sales_data(const string &b) : bookNo(b) {}
Sales_data(const string &b, unsigned u, double p) : bookNo(b), units_sold(u), revenue(p * u) {}
Sales_data(istream &is) { read(is, *this); }
//關于Sales_data對象的操作
string isbn() const { return bookNo; }
istream &read(istream &is, Sales_data &item);
private:
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
double avg_price() const;
Sales_data &combine(const Sales_data &);
};
inline double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
Sales_data add(Sales_data lhs, const Sales_data rhs)
{
return lhs.combine(rhs);
}
istream &Sales_data::read(istream &is, Sales_data &item)
{
double price = 0.0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " " << item.revenue << " " << item.avg_price();
return os;
}
int main()
{
Sales_data total(cin);
print(cout, total) << endl;
return 0;
}
練習7.27
/******************************************************************************
* 給你自己的Screen類添加move、set和display函數,通過執行下面的代碼檢驗你的類是否正
* 确。
* Screen myScreen(5, 5, 'X');
* myScreen.move(4,0).set('#').display(cout);
* cout << "\n";
* myScreen.display(cout);
* cout << "\n";
*****************************************************************************/
#include <iostream>
using std::cout;
using std::endl;
using std::string;
class Screen
{
public:
using pos = string::size_type;
Screen() = default;
Screen(pos w) : width(w) {}
Screen(pos w, pos h) : width(w), height(h), contents(w * h, ' ') {}
Screen(pos w, pos h, char s) : width(w), height(h), contents(h * w, s) {}
Screen &set(char);
Screen &set(pos, pos, char);
Screen &display(std::ostream &);
const Screen &display(std::ostream &) const;
char get() const { return contents[cursor]; }
char get(pos, pos) const;
Screen &move(pos, pos);
private:
pos cursor = 0, width = 0, height = 0;
string contents;
void do_display(std::ostream &os) const { os << contents; }
};
inline Screen &Screen::display(std::ostream &os)
{
do_display(os);
return *this;
}
inline const Screen &Screen::display(std::ostream &os) const
{
do_display(os);
return *this;
}
inline Screen &Screen::set(char c)
{
contents[cursor] = c;
return *this;
}
inline Screen &Screen::set(pos r, pos col, char ch)
{
contents[r * width + col] = ch;
return *this;
}
char Screen::get(pos x, pos y) const
{
pos row = x * width;
return contents[row + y];
}
Screen &Screen::move(pos r, pos c)
{
pos row = r * width;
cursor = row + c;
return *this;
}
int main()
{
Screen myScreen(5, 5, 'X');
myScreen.move(4,0).set('#').display(cout);
cout << "\n";
myScreen.display(cout);
cout << "\n";
}
練習7.29
/******************************************************************************
* 修改你的Screen類,令move,set和display函數傳回Screen并檢查程式的運作結果,再上一
* 個練習中你的推測正确嗎?
*****************************************************************************/
#include <iostream>
using std::cout;
using std::endl;
using std::string;
class Screen
{
public:
using pos = string::size_type;
Screen() = default;
Screen(pos w) : width(w) {}
Screen(pos w, pos h) : width(w), height(h), contents(w * h, ' ') {}
Screen(pos w, pos h, char s) : width(w), height(h), contents(h * w, s) {}
Screen set(char);
Screen set(pos, pos, char);
Screen display(std::ostream &);
const Screen display(std::ostream &) const;
char get() const { return contents[cursor]; }
char get(pos, pos) const;
Screen move(pos, pos);
private:
pos cursor = 0, width = 0, height = 0;
string contents;
void do_display(std::ostream &os) const { os << contents; }
};
inline Screen Screen::display(std::ostream &os)
{
do_display(os);
return *this;
}
inline const Screen Screen::display(std::ostream &os) const
{
do_display(os);
return *this;
}
inline Screen Screen::set(char c)
{
contents[cursor] = c;
return *this;
}
inline Screen Screen::set(pos r, pos col, char ch)
{
contents[r * width + col] = ch;
return *this;
}
char Screen::get(pos x, pos y) const
{
pos row = x * width;
return contents[row + y];
}
Screen Screen::move(pos r, pos c)
{
pos row = r * width;
cursor = row + c;
return *this;
}
int main()
{
Screen myScreen(5, 5, 'X');
myScreen.move(4, 0).set('#').display(cout);
cout << "\n";
myScreen.display(cout);
cout << "\n";
}
練習7.31
/******************************************************************************
* 定義一對類X和Y,其中X包含一個指向Y的指針,而Y包含一個類型為X的對象。
*****************************************************************************/
#include <iostream>
using std::cout;
class Y;
class X
{
public:
unsigned x = 0;
Y *s;
};
class Y
{
public:
unsigned y = 0;
X s;
};
int main()
{
X x1;
Y y1;
x1.s = &y1;
x1.x = 1;
y1.s = x1;
y1.y = 2;
cout << x1.x << " " << x1.s->y << " " << y1.y << " " << y1.s.x << "\n";
return 0;
}
練習7.32
/******************************************************************************
* 定義你自己的Screen和Window_mgr,其中clear是Window_mgr的成員,是Screen的友元
*****************************************************************************/
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::string;
using std::vector;
class Window_mgr;
class Screen
{
friend Window_mgr;
public:
using pos = string::size_type;
Screen() = default;
Screen(pos w) : width(w) {}
Screen(pos w, pos h) : width(w), height(h), contents(w * h, ' ') {}
Screen(pos w, pos h, char s) : width(w), height(h), contents(h * w, s) {}
Screen &set(char);
Screen &set(pos, pos, char);
Screen &display(std::ostream &);
const Screen &display(std::ostream &) const;
char get() const { return contents[cursor]; }
char get(pos, pos) const;
Screen &move(pos, pos);
private:
pos cursor = 0, width = 0, height = 0;
string contents;
void do_display(std::ostream &os) const { os << contents; }
};
class Window_mgr
{
public:
using ScreenIndex = vector<Screen>::size_type;
void clear(ScreenIndex);
vector<Screen> screens{Screen(16, 10, '#')};
};
void Window_mgr::clear(ScreenIndex i)
{
Screen &s = screens[i];
s.contents = string(s.height * s.width, ' ');
}
inline Screen &Screen::display(std::ostream &os)
{
do_display(os);
return *this;
}
inline const Screen &Screen::display(std::ostream &os) const
{
do_display(os);
return *this;
}
inline Screen &Screen::set(char c)
{
contents[cursor] = c;
return *this;
}
inline Screen &Screen::set(pos r, pos col, char ch)
{
contents[r * width + col] = ch;
return *this;
}
char Screen::get(pos x, pos y) const
{
pos row = x * width;
return contents[row + y];
}
Screen &Screen::move(pos r, pos c)
{
pos row = r * width;
cursor = row + c;
return *this;
}
int main()
{
Window_mgr my_screens;
my_screens.screens[0].display(cout);
cout << endl;
my_screens.clear(0);
my_screens.screens[0].display(cout);
return 0;
}
練習7.38
/******************************************************************************
* 有些情況下我們希望提供cin作為接受istream參數的構造函數的預設實參,請聲明這樣的構造
* 函數。
*****************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
using std::istream;
class A
{
public:
A(istream &is = cin) { is >> a; }
unsigned a = 0;
};
int main()
{
A q(cin);
cout << q.a << "\n";
A w;
cout << w.a << "\n";
return 0;
}
練習7.40
/******************************************************************************
* 從下面的抽象概念中選擇一個(或者你自己指定一個),思考這樣的類需要哪些資料成員,提
* 供一組合理的構造函數并闡明這樣做的原因。
* (a)Book (b)Date (c)Employee
* (d)Vehicle (e)Object (f)Tree
*****************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
using std::istream;
class Date
{
public:
Date() = default;
Date(unsigned y, unsigned m, unsigned d) : year(y), month(m), day(d) {}
Date(unsigned y, unsigned m, unsigned d, unsigned h, unsigned mi, unsigned s) : year(y), month(m), day(d), hour(h), minute(mi), second(s) {}
Date(istream &is) { is >> year >> month >> day >> hour >> minute >> second; }
void display();
private:
unsigned year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
};
void Date::display()
{
cout << year << "-" << month << "-" << day << " " << hour << ":" << minute << ":" << second;
}
int main()
{
Date d1, d2(1234, 5, 6), d3(7890, 12, 3, 4, 56, 7), d4(cin);
d1.display();
cout << "\n";
d2.display();
cout << "\n";
d3.display();
cout << "\n";
d4.display();
cout << "\n";
return 0;
}
練習7.41
/******************************************************************************
* 使用委托構造函數重新編寫你的Sales_data類,給每個構造函數體添加一條語句,令其一旦執
* 行就列印一條資訊。用各種可能的方式分别建立Sales_data對象,認真研究每次輸出的資訊直
* 到你确實了解了委托構造函數的執行順序。
*****************************************************************************/
#include <iostream>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::istream;
using std::ostream;
using std::string;
class Sales_data
{
friend Sales_data add(Sales_data, const Sales_data);
friend ostream &print(ostream &, const Sales_data &);
public:
Sales_data() : Sales_data("", 0, 0) { cout << "委托構造函數已執行!\n"; }
Sales_data(const string &b) : Sales_data(b, 0, 0) { cout << "委托構造函數已執行!\n"; }
Sales_data(const string &b, unsigned u, double p) : bookNo(b),
units_sold(u),
revenue(p * u) {}
Sales_data(istream &is) : Sales_data()
{
read(is, *this);
cout << "委托構造函數已執行!\n";
}
//關于Sales_data對象的操作
string isbn() const { return bookNo; }
istream &read(istream &is, Sales_data &item);
private:
string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
double avg_price() const;
Sales_data &combine(const Sales_data &);
};
inline double Sales_data::avg_price() const
{
if (units_sold)
return revenue / units_sold;
else
return 0;
}
Sales_data &Sales_data::combine(const Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成員加到this對象的成員上
revenue += rhs.revenue;
return *this;
}
Sales_data add(Sales_data lhs, const Sales_data rhs)
{
return lhs.combine(rhs);
}
istream &Sales_data::read(istream &is, Sales_data &item)
{
double price = 0.0;
is >> item.bookNo >> item.units_sold >> price;
item.revenue = price * item.units_sold;
return is;
}
ostream &print(ostream &os, const Sales_data &item)
{
os << item.isbn() << " " << item.units_sold << " "
<< item.revenue << " " << item.avg_price();
return os;
}
int main()
{
Sales_data total,total1("asd"),total2("qwer",1,3),total3(cin);
print(cout,total)<<endl;
print(cout,total1)<<endl;
print(cout,total2)<<endl;
print(cout,total3)<<endl;
return 0;
}
練習7.42
/******************************************************************************
* 對于你在練習7.40(參見7.5.1節,第261頁)中編寫的類,确定哪些構造函數可以使用委托。
* 如果可以的話,編寫委托構造函數。如果不可以,從抽象概念清單中重新選擇一個你認為可以
* 使用委托構造函數的,為挑選出的這個概念編寫類定義。
*****************************************************************************/
#include <iostream>
using std::cin;
using std::cout;
using std::istream;
class Date
{
public:
Date() : Date(0, 0, 0, 0, 0, 0) {}
Date(unsigned y, unsigned m, unsigned d) : Date(y, m, d, 0, 0, 0) {}
Date(unsigned y, unsigned m, unsigned d, unsigned h, unsigned mi, unsigned s) : year(y), month(m), day(d), hour(h), minute(mi), second(s) {}
Date(istream &is) : Date() { is >> year >> month >> day >> hour >> minute >> second; }
void display();
private:
unsigned year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
};
void Date::display()
{
cout << year << "-" << month << "-" << day << " " << hour << ":" << minute << ":" << second;
}
int main()
{
Date d1, d2(1234, 5, 6), d3(7890, 12, 3, 4, 56, 7), d4(cin);
d1.display();
cout << "\n";
d2.display();
cout << "\n";
d3.display();
cout << "\n";
d4.display();
cout << "\n";
return 0;
}
練習7.43
/******************************************************************************
* 假定有一個名為NoDefault的類,它有一個接受int的構造函數,但是沒有預設構造函數。定義
* 類C,C有一個Nodefault類型的成員,定義C的預設構造函數。
*****************************************************************************/
#include <iostream>
class NoDefault
{
public:
NoDefault(int i) {}
};
class C
{
public:
C() = default;
private:
NoDefault n;
};
int main()
{
C c; //無法引用 "C" 的預設構造函數 -- 它是已删除的函數
return 0;
}
練習7.53
/******************************************************************************
* 定義你自己的Debug。
*****************************************************************************/
#include <iostream>
using std::cerr;
class Debug
{
public:
constexpr Debug(bool b = true) : hw(b), io(b), ot(b) {}
constexpr Debug(bool i, bool h, bool o) : io(i), hw(h), ot(o) {}
constexpr bool any() { return io || hw || ot; }
void set_io(bool b) { io = b; }
void set_hw(bool b) { hw = b; }
void set_ot(bool b) { ot = b; }
private:
bool io;
bool hw;
bool ot;
};
int main()
{
Debug io_sub(false, true, false);
if (io_sub.any())
cerr << "io,hw,ot中至少有一個沒有出錯!\n";
Debug prod(false);
if (prod.any())
cerr<<"io,hw,ot全都不錯!\n";
return 0;
}
練習7.57
/******************************************************************************
* 編寫你自己的Account類。
*****************************************************************************/
#include <iostream>
using std::cout;
using std::string;
class Account
{
public:
void calculate() { amount += amount * interestRate; }
static double rate() { return interestRate; }
static void rate(double);
private:
string owner;
double amount;
static double interestRate;
static double initRate();
};
double Account::interestRate = 0.12;
void Account::rate(double newRate)
{
interestRate = newRate;
}
int main()
{
Account ac;
ac.rate(0.34);
ac.calculate();
cout << ac.rate() << "\n";
return 0;
}