1.异常类型与其的生命周期 2匿名对象

异常类型的生命周期

定义一个copyFile函数将一个文件中的内容以二进制的方式读出来并以二进制的方式写入另一个文件中,
并且定义一个类ErrorException用来检测错误
class ErrorException {
public:
ErrorException() { printf("默认构造函数\n"); num = 1; }
ErrorException(const ErrorException& error) { printf("拷贝构造函数\n"); num = 2; }
~ErrorException() { printf("析构函数<%d>\n",num); }
int num;
};

int copyFile(const char* dest, const char* src)throw(int,float,ErrorException) {
FILE* fp1 = NULL;
FILE* fp2 = NULL;

fopen_s(&fp1, src, "rb");
if (fp1 == NULL) {
	ErrorException error;
	throw error;
}

fopen_s(&fp2, dest, "wb");
if (fp2 == NULL) {
	throw -1;
}

char buffer[1024];
int writeLen, readLen;

while (readLen = (fread(buffer, 1, 1024, fp1))) {
	printf("readLen = %d\n", readLen);
	writeLen = fwrite(buffer, 1, readLen, fp2);
	printf("writeLen = %d\n", writeLen);
	if (readLen != writeLen) {
		throw 0.01f;
	}
}

return 0;

}

然后在main函数中调用这个方法:
int main(void) {
try {
printf("copyFile--catch\n");
copyFile("dest.txt", "src.txt");
}
catch (int error) {
printf("出现异常啦:%d\n", error);
}
catch (float error) {
printf("出现异常啦:%f\n", error);
}
catch (ErrorException error) {
error.num = 10;
printf("抓到Errorexcpetion了!\n");
}
catch (...) {
printf("没抓到!\n");
}

system("pause");
return 0;

}
开始调试程序,如果我们的同名文件夹中没有src.txt这个文件,则在函数copyFile中,fp1 = NULL,因此创建一个error对象
if (fp1 == NULL) {
ErrorException error;
throw error;
}
抛出这个error,再来看看控制台输出:
copyFile2--catch
默认构造函数
拷贝构造函数
拷贝构造函数
析构函数<1>
抓到Errorexcpetion了!
析构函数<10>
析构函数<2>
请按任意键继续. . .
为什么会这样,我们来分析一下:
首先语句ErrorException error; 调用了默认构造构造函数构造了一个类error,然后将其抛出:throw error,如何将其抛出,与函数返回值类似,这里创建了一个匿名对象来作为函数的返回值,这个匿名对象就是用拷贝构造函数将error给拷贝构造了,姑且将这个匿名对象称为temp,然后在将其在外面接住:ErrorException error(tmp);又调用了一次拷贝构造函数,从控制台输出我们也可以看出析构函数先删除的是的是error然后是匿名对象temp,在}之前就对这两个对象析构了。

改进

基于这个东西,我们改一下代码,可以将抛出接住这个过程更加有效率:
首先if (fp1 == NULL) {
/ErrorException error;
throw error;
/
throw ErrorException();
}
然后catch (ErrorException& error) {//这里改为引用类型,就不会再有新构建的对象
error.num = 10;
printf("抓到Errorexcpetion了!\n");
}
执行后输出:
copyFile2--catch
默认构造函数
抓到Errorexcpetion了!
析构函数<10>
请按任意键继续. . .
仅仅使用了一次构造函数,和析构函数更有效率。
因为throw ErrorException();这里直接构造了匿名对象,ErrorException error = ErrorException();就是这个error,并抛出,并没有使用拷贝构造函数的过程。然后将这个匿名对象作为引用类型来接住。

猜你喜欢

转载自www.cnblogs.com/Ybossy/p/12770875.html