C++Primer第4版习题解答十四章Word格式.docx
- 文档编号:20369338
- 上传时间:2023-01-22
- 格式:DOCX
- 页数:30
- 大小:106.71KB
C++Primer第4版习题解答十四章Word格式.docx
《C++Primer第4版习题解答十四章Word格式.docx》由会员分享,可在线阅读,更多相关《C++Primer第4版习题解答十四章Word格式.docx(30页珍藏版)》请在冰豆网上搜索。
从标准输入设备读入数据,创建Sales_item对象item。
第三句:
首先调用接受一个string参数的Sales_item构造函数,创建一个临时对象,然后调用Sales_item的复合重载操作符+=,将这个Sales_item临时对象加到item对象上,
如果构造函数为explicit,则不能进行从string对象到Sales_item对象的隐式转换,第三句将不能被编译。
4。
string和vector类都定义了一个重载的==,可用于比较这些类的对象,指出下面的表达式中应用了哪个==版本。
strings;
vector<
string>
svec1,svec2;
“cobble”==“store”应用了C++语言内置版本的重载==
svec1[0]==svec2[0];
应用了string版本的重载==
svec1==svec2应用了vector版本的重载==
5。
列出必须定义为类成员的操作符。
赋值=,下标[],调用(),成员访问箭头->
6。
解释下面操作符是否应该为类成员,为什么?
(a)+(b)+=(c)++(d)->
(e)<
(f)&
(g)==(h)()
+,<
==,&
通常定义为非成员;
->
和()必须定义为成员,否则会出现编译错误;
+=和++会改变对象的状态,通常会定义为类成员。
7。
为下面的ChecoutRecord类定义一个输出操作符:
classCheckoutRecord
//..
private:
doublebook_id;
stringtitle;
Datedate_borrowed;
Datedate_due;
pair<
string,string>
borrower;
string,string>
*>
wait_list;
operator<
(ostream&
out,constCheckoutRecord&
s)
out<
s.book_id<
"
\t"
<
s.title<
s.date_borrowed<
s.date_due
<
;
out<
borrower:
"
s.borrower.first<
"
s.borrower.second<
endl;
wait_list:
for(vector<
const_iteratorit=s.wait_list.begin();
it!
=s.wait_list.end();
++it)
{
out<
(*it)->
first<
second<
}
returnout;
}
8。
在12.4节的习题中,你编写了下面某个类的框架:
(b)Date
为所选择的类编写输出操作符。
#include<
iostream>
usingnamespacestd;
classDate
Date(){}
Date(inty,intm,intd)
year=y;
month=m;
day=d;
friendostream&
operator<
(ostream&
constDate&
intyear,month,day;
operator<
out,constDate&
d)
year:
d.year<
<
month:
d.month<
day:
d.day<
intmain()
Datedt(1988,12,01);
cout<
dt<
system("
pause"
return0;
9。
给定下述输入,描述Sales_item输入操作符的行为。
(a)0-201-99999-91024.95
(b)1024.950-201-99999-9
(a)将0-201-99999-9读入赋给对象的isbn成员,将10给units_sold成员,revenue成员被设置为249.5
(b)首先将形参对象的isbn成员设置为10,然后因为输入的数据不符合要求,导致输入失败,从而执行else语句,将Sales_item对象复位为空对象,此时isbn为空string,units_sold和revenue都为0
10。
下述Sales_item输入操作符有什么错误?
operator>
(istream&
in,Sales_item&
s)
doubleprice;
in>
s.isbn>
s.units_sold>
price;
s.revenue=s.units_sold*price;
returnin;
如果将习题14.9中的数据作为输入,将会发生什么?
上述的输入操作符中缺少了对错误输入情况的判断与处理,会导致错误的情况发生。
(a)的输入没有问题,但是(b)的输入,将形参Sales_item对象的ISBN成员值为10,units_sold和revenue成员保持原值不变。
11。
为14.2.1节习题中定义的CheckoutRecord类定义一个输入操作符,确保该类操作符处理输入错误。
//…
friendistream&
CheckoutRecord&
//声明为类的友元
//…
istream&
(istream&
in,CheckoutRecord&
c)
Inputbookid(double)andtitle(string):
\n"
;
c.book_id>
c.title;
//InputDatadata_borrowedanddata_due
cout<
Inputdata_borrowed(3ints:
year,month,day):
in>
c.date_borrowed;
//.year>
c.date_borrowed.month>
c.date_borrowed.day;
//InputDatadata_dueanddata_due
Inputdata_due(3ints:
c.date_due;
//.year>
c.date_due.month>
c.date_due.day;
//Inputthepair<
borrower
Inputthepair<
borrower(string):
c.borrower.first>
c.borrower.second;
if(!
in)
{
c=CheckoutRecord();
returnin;
}
//Inputwait_list
Inputthewait_list(string):
c.wait_list.clear();
while(in)
{
pair<
*ppr=newpair<
in>
ppr->
first>
second;
if(!
{
deleteppr;
returnin;
}
c.wait_list.push_back(ppr);
}
输入错误的情况:
输入正确的情况:
12。
编写Sales_item操作符,用+进行实际加法,而+=调用+。
与本节中操作符的实现方法相比较,讨论这个方法的缺点。
Sales_itemSales_item:
operator+(constSales_item&
rhs)
units_sold+=rhs.units_sold;
revenue+=rhs.revenue;
return*this;
将下面定义的非成员+=操作符声明为类Sales_item的友元:
Sales_itemoperator+=(Sales_item&
lhs,constSales_item&
lhs=lhs+rhs;
returnlhs;
这个方法缺点:
在+=操作中需要创建和撤销一个临时Sales_item对象,来保存+操作的结果,没有本节中的方法简单有效。
13。
如果有,你认为Sales_item还应该有哪些其他的算术操作符?
定义你认为的该类应包含的那些。
还应有-操作符,定义为类的非成员,相应地还应该有-=复合操作符并定义为类的成员。
Sales_item&
Sales_item:
operator-=(constSalse_item&
units_sold-=rhs.units_sold;
revenue-=rhs.revenue;
Sales_itemoperator-(constSales_item&
lhs,constSales_item&
Sales_itemret(lhs);
ret-=rhs;
returnret;
14。
定义一个赋值操作符,将isbn赋值给Sales_item对象。
operator=(conststring&
sbn=s;
为14.2.1节习题中介绍的CheckoutRecord类定义赋值操作符。
主函数中定义了两个CheckoutRecord类的对象,调用了CheckoutRecord类的=赋值操作符,效果如下截图:
int_tmain(intargc,_TCHAR*argv[])
CheckoutRecordc1;
cin>
c1;
CheckoutRecordc2;
c2=c1;
//调用了类的赋值操作符=
std:
cout<
c2<
endl;
//输出对象c2的内容
//CheckoutRecord类中赋值操作符定义为:
//重载操作符=
CheckoutRecord&
CheckoutRecord:
operator=(constCheckoutRecord&
cr)
book_id=cr.book_id;
title=cr.title;
date_borrowed=cr.date_borrowed;
//前提:
必须在Date类里也重载操作符=
date_due=cr.date_due;
//asbefore
//对pair进行赋值操作
borrower.first=cr.borrower.first;
borrower.second=cr.borrower.second;
//对vector进行赋值操作
wait_list.clear();
//首先清空
const_iteratorit=cr.wait_list.begin();
it!
=cr.wait_list.end();
++it)
pair<
ppr->
first=(*it)->
first;
second=(*it)->
wait_list.push_back(ppr);
16。
CheckoutRecord类还应该定义其他赋值操作符吗?
如果是,解释哪些类型应该用作操作数并解释为什么。
为这些类型实现赋值操作符。
从应用角度考虑,可能会修改预约时间date_due,可通过设置新的赋值操作符来实现;
或者是往wait_list里添加排队读者,也可以通过设置新的赋值操作符来实现。
//setnewdate_due
operator=(const&
new_due)
date_due=new_due;
//addnewreaderswhowaitforsomebooks
operator=(conststd:
pair<
new_waiter)
*ppr=new_waiter;
wait_list.push_back(ppr);
17。
14.2.1节习题中定义了一个CheckoutRecord类,为该类定义一个下标操作符,从等待列表中返回一个名字。
下标重载:
operator[]
(constvector<
size_typeindex)
return*wait_list.at(index);
//下标操作符重载
constpair<
size_typeindex)const
18。
讨论用下标操作符实现这个操作的优缺点。
优点:
使用简单。
缺点:
操作的语义不够清楚,因为CheckoutRecord不是一个通常意义上的容器,而且等待者也不是CheckoutRecord容器中的一个元素,不易使人弄明白怎样用。
19。
提出另一种方法定义这个操作。
可以将这个操作定义成普通的函数,pair<
get_a_waiter(constsize_tindex)和constpair<
get_a_waiter(constsize_tindex)const.
20。
在ScreenPtr类的概略定义中,声明但没有定义赋值操作符,请实现ScreenPtr赋值操作符。
ScreenPtr&
operator=(constScreenPtr&
sp)
++sp.ptr->
use;
if(--ptr->
use==0)
deleteptr;
ptr=sp.ptr;
21。
定义一个类,该类保存一个指向ScreenPtr的指针。
为该类定义一个重载的箭头操作符。
classNoName
NoName(*p):
ps(newScreenPtr(p)){}
ScreenPtroperator->
()
return*ps;
constScreenPtroperator->
()const
~NoName()
deleteps;
ScreenPtr*ps;
22。
智能指针可能应该定义相等操作符和不等操作符,以便测试两个指针是否相等或不等。
将这些操作加入到ScreenPtr类。
classScreenPtr
friendinlinebooloperator==(constScreenPtr&
constScreenPtr&
friendinlinebooloperator!
=(constScreenPtr&
ScrPtr*ptr;
//operator==
inlinebooloperator==(constScreenPtr&
p1,constScreenPtr&
p2)
returnp1.ptr==p2.ptr;
//operator!
=
inlinebooloperator!
return!
(p1.ptr==p2-.ptr);
23。
CheckedPtr类表示指向数组的指针。
为该类重载下标操作符和解引用操作符。
使操作符确保CheckedPtr有效:
它应该不可能对超出数组末端的元素进行解引用或索引。
//下标操作符重载
int&
CheckedPtr:
operator[](constsize_tindex)
if(beg+index>
=end)
throwout_ot_range(“invalidindex“);
return*(beg+index);
constint&
operator[](constsize_tindex)const
//解引用操作符重载
intCheckedPtr:
operator*()
if(curr==end)
throwout_of_range(“invalidcurrentpointer”);
return*curr;
constint&
operator*()const
throwout_of_range(“invalidcurrentpointer”);
24。
习题14.23中定义的解引用操作符或下标操作符,是否也应该检查对数组起点之前的元素进行的解引用或索引?
解释你的答案。
对于下标操作符,应该进行检查,因为当用户给出的下标索引值小于0时,编译器不会出现编译错误,而会出现运行时错误。
应修改为:
=end||beg+index<
beg)
而对于解引用操作符,返回curr所指向的数组元素,在创建对象时已经将curr初始化为指向数组的第一个元素,只有当执行—操作时才会对curr进行减的操作,而—操作符已经对curr的值与数组起点进行了检查,所以不用再在这里检查。
25。
为了
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Primer 习题 解答 十四
![提示](https://static.bdocx.com/images/bang_tan.gif)