C++Primer-课后习题第十八章

本文答案,部分参考于C++ Primer 习题集

前面章节的习题答案

第一章

第二章

第三章

第四章

第五章

第六章

第七章

第八章

第九章

第十章

第十一章

第十二章

第十三章

第十四章

第十五章

第十六章

第十七章

配套的学习资料

https://www.jianguoyun.com/p/DTK5uJgQldv8CBjKv80D

18.1

(a) 异常对象r的类型是range_error

(b) 被抛出的异常对象是对指针p解引用的结果,其类型与p的静态类型相匹配.为exception.若写成throw p.则抛出的异常对象是exception *类型.

​ 读者可尝试编译,运行这几条语句,观察系统的提示.

18.2

在new操作后发生的异常使得动态分配的数组没有被撤销,从而造成内存泄漏.

18.3

void exercise(int *b,int *e){
	itn *p=new int[v.size()];
	try{
		ifstream in("line");
	}catch{
		delete p;
	}
}

18.4

修改为:

try{
}
catch(overflow_error eobj){
}
catch(const runtime_error &re){
}catch(exception){}

18.5

int main(){
	try{
	}
	catch(const exception &e){
		cerr<<e.what()<<endl;
		abort();
	}
	return 0;
}

18.6

(a) throw new exceptionType();
(b) throw 8;
(c) throw 11;

18.7

在这里插入图片描述

在这里插入图片描述

18.8

class MyTest_Base {
public:
	MyTest_Base() {
		cout << "开始准备销毁一个MyTest_base类型的对象" << endl;
		//把异常完全封装在析构函数内部
		try {
			throw std::exception("在析构函数中故意抛出一个异常,测试! ");
		}
		catch (.) {

		}
	}
	void Func()throw() {
		throw std::exception("故意抛出一个异常,测试!");
	}
	void Other() {}
};

18.9

Sales_data& Sales_data::operator-=(const Sales_data& rhs) {
	if (isbn() != rhs.isbn())
		throw isbn_mismatch("wrong isbns", isbn(), rhs.isbn());
	units_sold -= rhs.units_sold;
	revenue -= rhs.revenue;
	return *this;
}

18.10

Sales_data item1, item2, sum;

while (cin>>item1>>item2) {
	try {
		sum = item1 + item2;
		return sum;
	}
	catch (const isbn_mismatch& e) {
		cerr << e.what() << ": left isbn(" << e.left << ") right isbn(" << e.right << ")" << endl;
	}
}
Sales_data item1, item2, sum;
while (cin >> item1 >> item2) {
	sum = item1 + item2;
	return sum;
}

18.11

what 函数是在catch异常后提取基本信息的虚函数,what函数是确保不会抛出任何异常的.如果what函数抛出了异常,则会在新产生的异常中由于what函数继续产生异常,将会产生异常的死循环.所以what函数必须确保不抛出异常.

18.12

​ 将Query类似以及Query_base的类层次定义为命名空间chapter15的成员,并相应修改主函数中的代码(使用限定名引用这些类,或者使用相关的声明).

18.13

​ 通常,当需要和声明局部与文件的实体时,可以使用未命名的命名空间,即在文件的最外层作用域中定义未命名的命名空间.

18.14

mathLib::MatrixLib::matrix mathLib::matrixLib::operator *(const matrix &,const matrix &);

18.15

​ 一个using 指令使得特定命名空间中的所有名字都为空间的;而一个using声明只能引入特定命名空间的一个成员.

18.16

在这里插入图片描述

18.17

在这里插入图片描述

在这里插入图片描述

18.18

​ 如果mem1是string类型,编译器除了在常规作用域中查找匹配的swap外,还会查找string所属的命名空间是否有string类型特定版本的swap函数,但对string而言,找到的就是std::swap,完成两个字符串内容的交换.

​ 若meme1是int类型,由于int是内置类型,没有特定版本的swap,只会在常规作用域中查找,由于using声明的作用,最终会调用std::swap,完成两个int的交换.

18.19

​ 将直接使用标准库版本的swap,而不会查找特定版本的swap或常规作用域中的其他swap.

18.20

在这里插入图片描述

18.21

(b) 错误,在一个派生类列表中,同一基类只能出现一次,这里List出现了两次.

18.22

(1) A的构造函数

(2) B的构造函数

(3)C的构造函数

(4) X的构造函数

(5) Y的构造函数

(6) Z的构造函数

(7) MI的构成函数

18.23

​ 因为C对B的继承是私有继承,使得在D中B的默认构造函数成为不可访问的.所以尽管存在从"D*“到"B*”,以及从"D*"到"A*"的转换,但这些转换不可访问.

18.24

​ 如果使用ZooAnimal指针,则只能使用ZooAnimal类中定义的操作。

​ pb->print(count);通过基类指针调用虚函数,使用动态绑定,pb目前指向Panda对象,随意调用Panda::print(ostream&).

​ pb->cuddle();因为ZooAnimal类中没有定义cuddle操作,所以该调用出错.

​ pb->highlight();因为zooAnimal类中没有定义highlight操作,所以该调用出错.

​ delete pb;因为ZooAnimal类中定义了虚析构函数,所以Panda类中的析构函数也是虚函数,因此delete pb;通过虚机制调用Panda析构函数,随着Panda析构函数的执行.依次调用Endangered,Bear和ZooAnimal的析构函数.

​ 所以,通过指向Panda对象的Bear指针或ZooAnimal指针进行上述调用.将以同样方式确定函数调用.

18.25

a,b,c都是通过基类指针调用虚函数print,这些基类指针当前都指向Mi类对象,所以都调用Mi::print(); d,e,f都通过基类指针删除对象这些基类指针当前都指向Mi类对象,所以都通过虚机制调用Mi析构函数,随着Mi析构函数的执行,依次调用D2,Base2,D1和Base1的析构函数.

18.26

​ 因为mi,print(42),通过MI类对象调用print函数,编译器通过了名字查找,确定调用的是MI类中定义的print函数,但是MI类中定义的print函数需要std::vector 类型的参数,所以该调用是错误的.

​ 改正,将MI中print的声明改为void print(int);该print调用即可正确编译和执行

18.27

​ (a) MI::foo中可见名字有:ival,dval,cval,sval,fval,dvec和print

​ (b) Dval和print

​ © dval=Base1::dval+Derivaed::dval;

​ (d) fval=dvec.back()

​ (e) sval[0]=cval;

18.28

在这里插入图片描述

18.29

在这里插入图片描述

18.30

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值