目录
7.1
7.2
7.3
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是否指向为空
思路:将可能出现异常的语句放入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;
}
思路:分别为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;
}