C++ I/O操作
//引入头文件
#include <fstream>
//文件写操作
ofstream out("myfile.txt");
out << "hello_world" << " " << 12 << " "<<'c' << endl;
out.close();
//文件读操作
ifstream in("myfile.txt");
string data1;
int data2;
char data3;
in >> data1 >> data2 >> data3;
cout << data1 << " " << data2 << " " << data3 << endl;
in.close();
C++ I/O异常
对于强制异常处理操作,产生异常后,运行会中断于异常处。
Q1:异常涉及关键字?
- throw:抛出异常
- try/catch:
(会随函数调用顺序逐级上抛,直至抛到有异常处理模块/抛到主函数显示异常)
try语句块——可能发生异常的代码
catch语句块——try后,若干个catch{}负责处理具体的异常类型
Q2:异常的栈展开是怎么回事?
函数抛出的异常会沿着函数调用链逆向抛出,直至:
1)抛到有异常处理模块,进行异常处理;
2) 抛到主函数显示异常,系统会调用terminate => abort 终止进程执行。
Q3:举一些产生异常的例子,还有怎么解决?
//ex.1
class Test
{
public:
Test(int data):ptr1(new int(data)), ptr2(new int(data))
{
cout << "Test()" << endl;
throw "构造函数中抛出的异常字符串";
}
~Test()
{
cout << "~Test()" << endl;
}
private:
int *ptr1;
int *ptr2;
//解决方法:利用智能指针在栈上自动释放的特点
//unique_ptr<int> ptr1;
//unique_ptr<int> ptr2;
};
此时,对Test类进行实例化运行时,会抛出异常产生异常中断,
并且测试的打印语句只输出了 "Test()" ,说明对象并未析构
//ex.2
try
{
int *p1 = new int;
int *p2= new int;
//解决方法:利用智能指针在栈上自动释放的特点,
// 直接替换当前代码里的new和delete操作
//unique_ptr<int> p1(new int);
//unique_ptr<int> p1(new int);
delete p1;
delete p2;
}
catch(const bad_alloc& e)//内存分配失败异常捕获
{}
此时,若p2内存分配失败,catch捕获到该异常产生中断,系统不会再调用delete对之前已分配成功的p1进行内存资源释放。
Q4:构造函数和析构函数能不能抛出异常?
构造函数:不能
例如上述在构造函数中抛出异常产生异常中断,对象没有构造成功,所以对象的析构函数就不会再调用了,导致内存无法释放。