Essential C++第七章习题

目录

7.1

7.2

7.3


7.1

1.类型不符:ifstream constructor接受的参数类型为const char*而非string,可以做出如下修改

ifstream infile(file_name.c_str());

2.文件可能打开不成功,应增加判断语句:

if(!infile) //打开失败

3.所打开文件中的数据类型未知,若文件内含有的数据是文字,则将文字存入整型elem_cnt中则会发生错误。

4.在处理指针时,必须随时主义指针是否的确指向实际存在的对象,如果allocate_array()无法分配足够内存,指针pi则会被设置为0,因此应做如下检验:

if(!pi) //判断指针pi是否指向为空

7.2

思路:将可能出现异常的语句放入try语段中,并在try语段之后紧跟相应的catch语句来捕获异常。

三个可能出现异常的语句抛出的异常类型分别为const noMem(标准异常基类exception的派生类),int,string,因此后续的catch语句参数应为此三种类型。

C++代码:


int* alloc_and_int(string file_name)
{
	ifstream infile(file_name.c_str());
	if (!infile)
	{
		return 0;
	}

	int elem_cnt;
	infile >> elem_cnt;
	if (!infile)
	{
		return 0;
	}

	try
	{
		int* pi = allocate_array(elem_cnt);
		int elem;
		int index = 0;
		while (infile >> elem && index < elem_cnt)
		{
			pi[index++] = elem;
		}

		sort_array(pi, elem_cnt);
		register_data(pi);
	}
	catch (const noMem& memFail)
	{
		cerr << "alloc_and_init:allocate_array failure!" << endl;
		cout << memFail.what() << endl;
		return 0;
	}
	catch (int& sortFail)
	{
		cerr << "alloc_and_init():sort_array failure!" << endl;
		cerr << "thrown integer value: " << sortFail << endl;
		return 0;
	}
	catch (string& registerFail)
	{
		cerr << "alloc_and_int():register_data failure" << endl;
		cerr << "thrown string values:" << registerFail << endl;
		return 0;
	}
	return pi;
}

7.3

思路:分别为pop()和push()两个函数设计PopOnEmpty和PushOnFull()两个异常类

Pop:

void pop(elemType& elem)
{
	if (empty())
	{
		throw PopOnEmpty();
	}
	elem = _stack[--_top];
	_stack.pop_back();
}

Push:

void push(const elemType& elem)
{
	if (!full())
	{
		_stack.push_back(elem);
		++_top;
		return;
	}
	throw PushOnFull();
}

接下来是设计这两个异常类

为了让这两个Stack异常可以完全不知情的被其他组件捕获,应当为它们融入StackException继承体系中去,而StackException又派生自标准库提供的logic_error class(抽象基类exception的派生类,定义在头文件中)

StackException:

class StackException :public logic_error
{
public:
	StackException(const char* what) :_what(what) { };
	const char* what()const { return _what.c_str() };
protected:
	string _what;
};

PopOnEmpty:

class PopOnEmpty :public StackException
{
public:
	PopOnEmpty() :StackException("Pop on Empty Stack"); //调用StackException的constructor给protected成员_what赋值
}

PushOnFull:

class PushOnFull :public StackException
{
public:
	PushOnFull() :StackException("Push on Full Stack");
};

至此,以下任意一个catch子句都能处理类型为PopOnEmpty 和 PushOnFull的异常:

参数为最初的抽象基类:

catch (const exception&stke)
{
	log(stke.what());
	return;
}

参数为抽象基类的派生类:

catch (const logic_error&stke)
{
	log(stke.what());
	return;
}

参数为logic_error的派生类:

catch (const StackException& stke)
{
	log(stke.what());
	return;
}

参数为PopOnEmpty类或PushOnFull类:

catch (const PopOnEmpty& stke)
{
	log(stke.what());
	return;
}
catch (const PushOnFull& stke)
{
	log(stke.what());
	return;
}

你可能感兴趣的:(Essential,C++,C++,c++,开发语言)