Exercises Section 7.1.1
Ex7.1
#include <iostream>
#include <string>
struct Sales_data
{
std::string bookNo;
unsigned units_sold = 0 ;
double revenue = 0.0 ;
};
int main ()
{
Sales_data total;
if (std::cin >> total.bookNo >> total.units_sold >> total.revenue)
{
Sales_data trans;
while (std::cin >> trans.bookNo >> trans.units_sold >> trans.revenue)
{
if (total.bookNo == trans.bookNo)
total.units_sold += trans.units_sold;
else
{
std::cout << total.bookNo << " " << total.units_sold << " " << total.revenue << std::endl;
total = trans;
}
}
std::cout << total.bookNo << " " << total.units_sold << " " << total.revenue << std::endl;
}
else
{
std::cerr << "No data?!" << std::endl;
return -1 ;
}
system ("pause" );
return 0 ;
}
Exercises Section 7.1.2
Ex7.2
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 ;
}
Ex7.3
#include <iostream>
#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 ;
}
int main ()
{
Sales_data total;
if (std::cin >> total.bookNo >> total.units_sold >> total.revenue)
{
Sales_data trans;
while (std::cin >> trans.bookNo >> trans.units_sold >> trans.revenue)
{
if (total.isbn () == trans.isbn ())
total.combine (trans);
else
{
std::cout << total.bookNo << " " << total.units_sold << " " << total.revenue << std::endl;
total = trans;
}
}
std::cout << total.bookNo << " " << total.units_sold << " " << total.revenue << std::endl;
}
else
{
std::cerr << "No data?!" << std::endl;
return -1 ;
}
system ("pause" );
return 0 ;
}
Ex7.4
struct Person
{
std::string name;
std::string address;
};
Ex7.5
struct Person
{
std::string getName () const { return name; }
std::string getAddr () const { return address; }
std::string name;
std::string address;
};
Exercises Section 7.1.3
Ex7.6
std::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;
}
std::ostream &print (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;
}
Ex7.7
#include <iostream>
#include <string>
using namespace std;
struct Sales_data
{
string isbn () const { return bookNo; }
Sales_data &combine ( const Sales_data &) ;
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 ;
}
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;
return os;
}
Sales_data add (const Sales_data &lhs, const Sales_data &rhs)
{
Sales_data sum = lhs;
sum.combine (rhs);
return sum;
}
int main ()
{
Sales_data total;
if (read (cin, total))
{
Sales_data trans;
while (read (cin, trans))
{
if (total.isbn () == trans.isbn ())
total = add (total, trans);
else
{
print (cout, total);
cout << endl;
total = trans;
}
}
print (cout, total);
cout << endl;
}
else
{
std::cerr << "No data?!" << std::endl;
return -1 ;
}
system ("pause" );
return 0 ;
}
Ex7.8
因为 read () 函数需要传入 cin,改变了定义的变量值;
print () 函数不需要改变变量值故而定义为 const
Ex7.9
struct Person
{
std::string getName () const { return name; }
std::string getAddr () const { return address; }
std::string name;
std::string address;
};
std::istream &read (istream &is, Person &item)
{
is >> item.name >> item.address;
return is;
}
std::ostream &print (ostream &os, const Person &item)
{
os << item.getName () << " " << item.getAddr ();
return os;
}
Ex7.10
if (read (read (cin, data1), data2)
Exercises Section 7.1.4
Ex7.11 7.12 7.13 7.14
#include <iostream>
#include <string>
using namespace std;
struct Sales_data
{
Sales_data () = default ;
Sales_data (const std::string &s) : bookNo (s) {}
Sales_data (const std::string &s, unsigned n, double p) : bookNo (s), units_sold (n), revenue (p * n) {}
Sales_data (std::istream &);
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 ;
}
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 << endl;
return os;
}
int main ()
{
Sales_data s1 ("" , 0.0 , 0.0 ) ;
Sales_data s2 ("0-201-78134-X" ) ;
Sales_data s3 ("0-201-78134-X" , 10 , 0.2 ) ;
Sales_data s4;
read (cin, s4);
print (cout, s1);
print (cout, s2);
print (cout, s3);
print (cout, s4);
system ("pause" );
return 0 ;
}
Ex7.15
struct Person
{
Person () = default ;
Person (const std::string &s) : name (s) {}
Person (const std::string &s, const std::string &a) : name (s), address (a) {}
string getName () const { return name; }
string getAddr () const { return address; }
std::string name;
std::string address;
};
Exercises Section 7.2
Ex7.16
public :后面应该跟函数和方法
private :后面应该跟定义的变量
Ex7.17
不使用 public 和 private 的话, class 后面的为 private 成员,struct 后面的为 public 成员
Ex7.18
封装就是只提供使用该类的接口,而不表明该类是如何实现的;
封装使使用者更方便使该类
Ex7.19
构造函数和 getName ()、getAddr ()应该为 public 成员;
变量 name 和 address 应该为 private 成员
Exercises Section 7.2.1
Ex7.20
被声明为一个类的友元函数可以调用该类的 private 成员;
友元给函数提供了方便,但是也增加了函数的不安全性
Ex7.21
class Sales_data
{
public :
Sales_data () = default ;
Sales_data (const std::string &s) : bookNo (s) {}
Sales_data (const std::string &s, unsigned n, double p) : bookNo (s), units_sold (n), revenue (p * n) {}
Sales_data (std::istream &);
std::string isbn () const { return bookNo; }
Sales_data &combine ( const Sales_data &) ;
private :
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 ;
}
Ex7.22
class Person
{
public :
Person () = default ;
Person (const std::string &s) : name (s) {}
Person (const std::string &s, const std::string &a) : name (s), address (a) {}
string getName () const { return name; }
string getAddr () const { return address; }
private :
std::string name;
std::string address;
};
Exercises Section 7.3.1
Ex7.23 7.24
class Screen
{
public :
typedef std::string::size_type pos;
Screen () = default ;
Screen (pos ht, pos wd, char c) : height (ht), width (wd), contents (ht * wd, c) {}
Screen (pos ht, pos wd, char c) : heiget (ht), width (wd), cursor (c) {}
char get () const { return contents[curosr]; }
inline char get (pos ht, pos wd) const ;
private :
pos cursor = 0 ;
pos height = 0 , width = 0 ;
std::string contents;
};
Ex7.25
如果未显式定义带参构造函数,那么默认构造函数就是安全的。
Ex7.26
class Sales_data
{
public :
Sales_data () = default ;
Sales_data (const std::string &s) : bookNo (s) {}
Sales_data (const std::string &s, unsigned n, double p) : bookNo (s), units_sold (n), revenue (p * n) {}
Sales_data (std::istream &);
std::string isbn () const { return bookNo; }
Sales_data &combine ( const Sales_data &) ;
private :
inline double avg_price () const { return units_sold ? revenue / units_sold : 0 ; }
std::string bookNo;
unsigned units_sold = 0 ;
double revenue = 0.0 ;
};
Exercises Section 7.3.2
Ex7.27
#include <iostream>
#include <string>
using namespace std;
class Screen
{
public :
typedef std::string::size_type pos;
Screen () = default ;
Screen (pos ht, pos wd, char c) : height (ht), width (wd), contents (ht * wd, c) {}
char get () const { return contents[cursor]; }
inline char get (pos ht, pos wd) const ;
Screen &move (pos r, pos c) ;
Screen &set (char ) ;
Screen &set (pos, pos, char ) ;
Screen &display (std::ostream &os) { do_display (os); return *this ; }
const Screen &display (std::ostream &os) const { do_display (os); return *this ; }
private :
void do_display (std::ostream &os) const { os << contents; }
pos cursor = 0 ;
pos height = 0 , width = 0 ;
std::string contents;
};
char Screen::get (pos r, pos c) const
{
pos row = r * width;
return contents[row + c];
}
inline Screen& Screen::move (pos r, pos c)
{
pos row = r * width;
cursor = row + c;
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 ;
}
int main ()
{
Screen myScreen (5 , 5 , 'X' ) ;
myScreen.move (4 , 0 ).set ('#' ).display (cout);
cout << "\n" ;
myScreen.display (cout);
cout << "\n" ;
system ("pause" );
return 0 ;
}
Ex7.28
只会对其副本进行修改,不会改变对象的值。
Ex7.29
Ex7.30
优点:比较明确
缺点:不够简洁
Exercises Section 7.3.3
Ex7.31
class X
{
Y *y;
};
class Y
{
X x;
};
Exercises Section 7.3.4
Ex7.32
class Screen
{
friend class Window_mgr ;
public :
typedef std::string::size_type pos;
Screen () = default ;
Screen (pos ht, pos wd, char c) : height (ht), width (wd), contents (ht * wd, c) {}
char get () const { return contents[cursor]; }
inline char get (pos ht, pos wd) const ;
Screen &move (pos r, pos c) ;
Screen &set (char ) ;
Screen &set (pos, pos, char ) ;
Screen &display (std::ostream &os) { do_display (os); return *this ; }
const Screen display (std::ostream &os) const { do_display (os); return *this ; }
private :
void do_display (std::ostream &os) const { os << contents; }
pos cursor = 0 ;
pos height = 0 , width = 0 ;
std::string contents;
};
char Screen::get (pos r, pos c) const
{
pos row = r * width;
return contents[row + c];
}
inline Screen &Screen::move (pos r, pos c)
{
pos row = r * width;
cursor = row + c;
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 ;
}
class Window_mgr
{
public :
using ScreenIndex = std::vector<Screen>::size_type;
void clear (ScreenIndex) ;
private :
std::vector<Screen> screens{Screen (24 , 80 , ' ' )};
}
void Window_mgr::clear (ScreenIndex i)
{
Screen &s = screens[i];
s.contents = string (s.height * s.width, ' ' );
}
Exercises Section 7.4
Ex7.33
pos Screen::size () const
{
return height * width;
}
Screen::pos Screen::size () const
{
return height * width;
}
Exercises Section 7.4.1
Ex7.34
当把 pos 类型声明放到最后,类会出错;前面定义的 pos 类的函数和变量都找不到该类。
Ex7.35
typedef string Type;
Type initVal () ;
class Exercise
{
public :
typedef double Type;
Type setVal (Type) ;
Type initVal () ;
private :
int val;
};
Type Exercise::setVal (Type parm)
{
val = parm + initVal ();
return val;
}
Exercises Section 7.5.1
Ex7.36
struct X
{
X (int i, int j) : base (i), rem (base % j) {}
int rem, base;
};
struct X
{
X (int i, int j) : base (i), rem (i % j) {}
int rem, base;
};
Ex7.37
Sales_data first_item (cin) ;
int main ()
{
Sales_data next;
Sales_data last ("9-999-99999-9" ) ;
}
Ex7.38
Sales_data (std::istream &is = cin);
Ex7.39
不合法;产生二义性
Ex7.40
class Book
{
public :
Book () = default ;
Book (const std::string s) : bookNo (s) {}
Book (const std::string s, const std::String n, const double p) : BookNo (s), author_name (n), price (p) {}
private :
std::string bookNo;
std::string author_name;
double price = 0.0 ;
};
Exercises Section 7.5.2
Ex7.41
class Sales_data
{
public :
Sales_data (const std::string &s, unsigned n, double p) : bookNo (s), units_sold (n), revenue (p * n) {}
Sales_data (std::istream &) : Sales_data ("" , 0 , 0 ) {}
Sales_data (const std::string &s) : Sales_data (s, 0 , 0 ) {}
Sales_data (std::istream &is) : Sales_data ("" , 0 , 0 ) { read (is, *this ); }
};
Exercises Section 7.5.3
Ex7.43
class NoDefault
{
public :
NoDefault (const int ) {}
};
class C
{
public :
C () : my_c (0 ) {}
private :
NoDefault my_c;
};
Ex7.44
vector<NoDefault> vec (10 ) ;
Ex7.45
vector<C> vec (10 ) ;
Ex7.46
a) 不正确;不提供构造函数的话编译器会提供默认构造函数
b) 不正确;默认构造函数不仅没有参数而且函数体中没有语句
c) 不正确;编译器提供默认构造函数不关心值是否有意义
d) 不正确;只有当没有显式提供任何构造函数时,编译器才会提供默认构造函数
Exercises Section 7.5.4
Ex7.47
防止构造函数进行隐式转换;
优点:可以减少一些难以看懂的代码产生
缺点:减少了能通过编译的代码
Ex7.48
string null_isbn ("9-999-99999-9" ) ;
Sales_data item1 (null_isbn) ;
Sales_data item2 ("9-999-99999-9" ) ;
Ex7.49
a) Sales_data &combine (Sales_data) ;
b) Sales_data &combine (Sales_data&) ;
c) Sales_data &combine (const Sales_data&) const ;
Ex7.50
struct Person
{
friend std::istream &read (std::istream &is, Person &person) ;
friend std::ostream &print (std::ostream &os, const Person &person) ;
public :
Person () = default ;
Person (const std::string sname, const std::string saddr) : name (sname), address (saddr) { }
explicit Person (std::istream &is) { read (is, *this ); }
std::string getName () const { return name; }
std::string getAddress () const { return address; }
private :
std::string name;
std::string address;
};
std::istream &read (std::istream &is, Person &person)
{
is >> person.name >> person.address;
return is;
}
std::ostream &print (std::ostream &os, const Person &person)
{
os << person.name << " " << person.address;
return os;
}
Ex7.51
vector的单参数构造函数声明为 explicit 避免了一些不必的隐式转换;
string 的单参数构造函数不声明为 explicit 可以方便使用者
Exercises Section 7.5.5
Ex7.52
struct Sales_data
{
std::string bookNo;
unsigned units_sold;
double revenue;
};
Sales_data item = {"978-0590353403" , 25 , 15.99 };
Exercises Section 7.5.6
Ex7.53
class Debug
{
public :
constexpr Debug (bool b = true ) : hw(b), io(b), other(b) { }
constexpr Debug (bool h, bool i, bool o) : hw(h), io(i), other(o) { }
constexpr bool any () { return hw || io || other; }
void set_io (bool b) { io = b; }
void set_hw (bool b) { hw = b; }
void set_other (bool b) { hw = b; }
private :
bool hw;
bool io;
bool other;
};
Ex7.54
不应该;声明为 constexpr 的函数应该包含一条 return 语句
Ex7.55
是的; a aggregate class must be a literal class
Exercises Section 7.6
Ex7.56
static 成员与该类相关,而不是类内的对象;
优点:每个 static 成员都无需存储公共数据,而且更改了数据,每个成员都能使用新值;
static 成员可以声明为它所属的类型;而非 static 成员只能声明为所属类
Ex7.57
class Account
{
public :
void calculate () { amount += amount * interestRate; }
static double rate () { return interestRate; }
static void rate (double ) ;
private :
std::string owner;
double amount;
static double interestRate;
static double initRate () ;
};
Ex7.58
class Example
{
public :
static double rate = 6.5 ;
static const int vecSize = 20 ;
static vector<double > vec (vecSize) ;
};
#include "example.h"
double Example::rate;
vector<double > Example::vec;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端