您的位置:首页 > 其它

异常和文件操作

2017-09-28 09:41 113 查看
引子:类型转换

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: