异常和文件操作

引子:类型转换

1)普通类型之间的转换:static_cast 凡是可以隐式转换的地方都可以用,在编译时进行类型识别

	a = ststic_cast<int>(d);

2)指针之间的转换:reinterpret_cast 可用来在指针和整型之间转换

	p = reinterpret_cast<int *>(pd);

3)层次间转换:dynamic_cast 在运行时进行类型识别,基类和派生类之间转换;类型匹配则成功,不不匹配则失败,返回NULL指针;

	Dog * p = dynamic_cast<Dog*>(p);

4)去掉只读属性:const_cast 只是去掉只读属性赋给前面的值,但其本身并无变化

	char* p = const_cast <char*>(str);


1、异常处理

异常是一种程序控制机制,与函数机制独立和互补。可以用来改变程序的控制结构,但在错误处理方面取得了巨大好处。

1)使用throw可以抛出异常,然后可以使用try{}catch{}语句块来捕获并处理异常。

1、把可能发生异常的代码放在try(try不是处理错误,而是处理异常)中,异常需要人为抛出。

2、异常是跨函数的

3、异常在捕获后:处理,不让其继续抛或者不处理,用throw继续往后抛

4、catch捕获后,要严格遵循类型匹配,不允许任何形式的类型转换

2)从try开始到throw期间,在栈上创建的所有对象,当异常抛出的时候会被全部释放。析构顺序与构造顺序相反,成为栈解旋。但是堆上的对象需要自己处理,不会自动释放的

3)异常接口声明:默认函数可以抛出任意类型的异常,但也可以限制抛出类型:

	void fun()throw(A,B,C);		// 该函数只能抛出ABC类型的异常
	void fun() throw(); 		// 该函数不能抛出任何类型的异常


4)异常变量的生命周期:

当抛出一个对象时,
1、拿一个普通变量去收,会有匿名对象产生,但它的生命周期会直到异常处理完毕。
2、当拿引用去接这个匿名对象时,不会产生多个备份。
3、去接对象指针时,若在栈上,在异常接收前就释放了,接到的指针不可使用,它是非法指针。
4、去接一个堆上的对象指针,该对象不会自动释放,需要手动调用delete去释放

catch的类型:引用和普通变量不能共存,但引用和指针可以共存

5)异常在类层次中使用:用这样一个数组类来举例:对数组初始化时对数组的个数进行有效检查。这样的类除了需要一般的构造函数,析构函数等之外,在需要几个相关错误的处理类,让它们都继承自eSize类(内部类),这样,在构造函数中根据条件抛出这些错误处理类。在main函数中用try语句建数组类并用多态的知识利用基类的引用接错误类。

6)C++标准提供了一组标准异常类,这些类以基类Exception开始,标准程序库中抛出的所有异常,都派生于该基类,这些类的派生都继承了一个成员函数what(),用于返回错误信息(返回类型是const char*),声明如下:

	virtual const char * what() const throw();


2、C++输入输出流

1)输入输出流:
标准设备:键盘,屏幕==>标准I/O
文件:读(in)写(out)文件==>文件I/O
内存:缓冲区、数组==>串I/O
2)
输入流:
	ch = cin.get();  cin.get(ch);	//getchar()
	cin.getline(str,100);		//fgets  (cin读不了空格)
	cin.ignore(3);			//忽略3个字节往后读
	ch = cin.peek();		//偷窥一个字节,并不撩
	cin.putchar(ch);		//吃完吐回到缓存区
3)文件操作
1、读出
	ofstream f("test"); 		// 定义一个文件输出流对象,对象创建成功则已打开
	f << "hello world" << endl;	// 把f当cout用
2、写入:类似读出
3、关闭:f.close();

/*
案例:设计一个数组类 MyArray,重载[]操作,
	数组初始化时,对数组的个数进行有效检查 
	1)index<0 抛出异常eNegative  
	2)index = 0 抛出异常 eZero  
	3)index>1000抛出异常eTooBig 
	4)eSize类是以上类的父类,实现有参数构造、并定义virtual void printErr()输出错误。
*/
#include <iostream>
using namespace std;

class MyArray
{
public:
	MyArray(int len)
	{
		if (len < 0)
		{
			throw eNegative(len);
		}
		if (len == 0)
		{
			throw eZero(len);
		}
		if (len > 1000)
		{
			throw eTooBig(len);
		}
		this->len = len;
		m_p = new int[len];
	}
	~MyArray()
	{
		if (m_p != NULL)
		{
			delete []m_p;
			m_p = NULL;
		}
		len = 0;
	}
	int &operator[](int index)
	{
		return m_p[index];
	}

	class eSize
	{
	public:
		eSize(int size)
		{
			this->size = size;
		}
		virtual void printErr() = 0;
	protected:
		int size;
	};
	class eNegative
	{
	public:
		eNegative(int size)
		{
			this->size = size;
		}
		void printErr()
		{
			printf("result < 0\n");
		}
	protected:
		int size;
	};
	class eZero
	{
	public:
		eZero(int size)
		{
			this->size = size;
		}
		void printErr()
		{
			printf("result = 0\n");
		}
	protected:
		int size;
	};
	class eTooBig
	{
	public:
		eTooBig(int size)
		{
			this->size = size;
		}
		void printErr()
		{
			printf("result > 1000\n");
		}
	protected:
		int size;
	};

protected:
	int len;
	int *m_p;
};
int main()
{
	try
	{
		MyArray a(3);
		for (int i = 0; i < 10; i++)
		{
			a[i] = i;
		}
	}
	catch(MyArray::eSize & e)	// 多态
	{
		e.printErr();
	}
	catch(...)
	{
		printf("others\n");
	}
	return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值