【C++】9.类型转换,c++异常处理,输入输出流-创新互联

1. 静态转换 static_cast
  1. 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。
    • 进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
      • Base *base=static_cast(base);
      • 把Child转为Base * ,是向上转化,安全!
    • 进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
      • Child * child=static_cast(child)
      • 将Base转为Child * ,是向下转换,不安全!
  2. 用于基本数据类型之间的转换,如把int转换成char,把char转换成int。这种转换的安全性也要开发人员来保证:double b = static_cast(int a);
2. 动态转换 dynamic_cast
  1. dynamic_cast主要用于类层次间的上行转换和下行转换;不支持基础数据类型.
  2. 在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;
  3. 在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全;
3. 常量转换const_cast
该运算符用来修改对象的const属性
不能直接对非指针和非引用的变量使用const_cast操作符去直接移除它的const.
  1. 常量指针被转化成非常量指针,并且仍然指向原来的对象;
const int* p = _NULL_;          //p本来是常量指针
int* np = const_cast(p);  //取出const,将常量指针被转化成非常量指针
  1. 非常量指针被转换成常量指针,并且仍然指向原来的对象;
int* pp = _NULL_;                                 //p本来是非常量
const int* npp = const_cast(pp);      //加上const,将非常量指针转换为常量指针
  1. 引用同理.
  2. 不能对非指针非引用的变量进行常量转换!
4.重新解释转换 reinterpret_cast
  1. 这是最不安全的一种转换机制,最有可能出问题。
  2. 主要用于将一种数据类型从一种类型转换为另一种类型。它可以将一个指针转换成一个整数,也可以将一个整数转换成一个指针.
5.C++异常
将[问题检测]和[问题处理]相分离
由[问题检测代码]可以抛出(throw)一个对象给[问题处理代码],通过这个对象的类型和内容,实际上完成了两个部分的通信,通信的内容是“出现了什么错误”。
1. 语法:
try{
	.....//要试图执行的部分
}catch(捕获类型){
	//throw;向上抛出
	......//异常处理
}//如果没有任何处理异常的地方,那么成员调用Terminate函数,终止程序
2. 异常严格类型匹配

(1)在方法中

创新互联公司主要从事网站制作、成都网站建设、网页设计、企业做网站、公司建网站等业务。立足成都服务陇南,10年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18982081108
void TestFunction**(){**
cout **<<** "开始抛出异常..." **<<** endl**;**
//throw 10; //抛出int类型异常
//throw 'a'; //抛出char类型异常
//throw "abcd"; //抛出char*类型异常
//throw myException();//抛出自定义异常(匿名对象)
}

(2)在main中

try{
		TestFunction();
	}
	catch (int){
		cout<< "抛出Int类型异常!"<< endl;
	}
	catch (char){
		cout<< "抛出Char类型异常!"<< endl;
	}
	catch (char*){
		cout<< "抛出Char*类型异常!"<< endl;
	}
	catch (string){
		cout<< "抛出string类型异常!"<< endl;
	}
	catch(MyException e){//抛出自定义异常
		e.printError();
	}
	//捕获所有异常
	catch (...){
		cout<< "抛出其他类型异常!"<< endl;
	}
3. 栈解旋unwinding

异常被抛出后,从进入try块起,到异常被抛掷前,这期间在栈上构造的所有对象,都会被自动析构。析构的顺序与构造的顺序相反,这一过程称为栈的解旋(unwinding).

4. 异常接口声明

(1)只能抛出int类型异常:void func() throw(int){}
(2)能抛出类型A,B,C及其子类型的异常:void func() throw(A,B,C){}
(3)不抛任何类型异常:void func() throw(){}
(4)如果一个函数抛出了它的异常接口声明所不允许抛出的异常,unexcepted函数会被调用,该函数默认行为调用terminate函数中断程序。

5. 异常变量生命周期
  1. 如果 MyException e, 会多开销一份数据,调用拷贝构造。
  2. 如果MyExcepiton* e,不new 提前释放对象;new自己管理delete
  3. 推荐MyException&e 容易些而且就一份数据
6.异常的多态使用 6.C++标准异常库

(1)系统标准库
![[Pasted image 20221016134510.png]]

(2)自己编写异常类

  1. 继承标准异常类。
  2. 该重载父类的what函数和虚析构函数。
  3. 因为栈展开的过程中,要复制异常类型,那么要根据你在类中添加的成员考虑是否提供自己的复制构造函数
    ①编写自己的异常类
class MyOutOfRange:public exception                //继承标准异常类
{
public:
	MyOutOfRange(const string  errorInfo)          //有参构造string类型
	{
		this->m_Error = errorInfo;
	}
	MyOutOfRange(const char * errorInfo)           //有参构造char *类型
	{
		this->m_Error = string( errorInfo);
	}
	virtual  ~MyOutOfRange()                        //重载虚析构函数
	{
	}
	virtual const char *  what() const               //重载what函数
	{
		return this->m_Error.c_str() ;               //string转char *的方法.c_str()
	}
	string m_Error;                                  //错误信息
};

②异常检测

if (age<= 0 || age >150)
{
//抛出异常 越界
//throw  out_of_range("年龄必须在0~150之间");          //标准库中的越界异常
//throw length_error("长度异常");                     //标准库中的长度异常
throw MyOutOfRange(("我的异常 年龄必须在0~150之间"));   //自己编写的异常
}

③异常处理

try
	{
		Person p(151);                 //这里年龄越界
	}
	catch ( out_of_range & e )         //标准库中的越界异常
	{
		cout<< e.what()<< endl;
	}
	catch (length_error & e)            //标准库中的长度异常
	{
		cout<< e.what()<< endl;
	}
	catch (MyOutOfRange e)               //自己编写的异常
	{
		cout<< e.what()<< endl;
	}
7.输入输出流 1.流的概念和流类库的结构

(1)标准I/O:标准设备的输入和输出
![[Pasted image 20221017091745.png]]
![[Pasted image 20221017091803.png]]
(2)文件I/O: 以外存磁盘文件为对象进行输入和输出
![[Pasted image 20221017092011.png]]
(3)(字符)串I/O:对内存中指定的空间进行输入和输出,通常指定一个字符数组作为存储空间

2.cin
  1. cin.get():读取输入的第一个字符
  2. cin.get(ch):等价于ch=cin.get()读取输入的第一个字符
  3. cin.get(buf,1024):读取输入的长度为1024字符串buf数组中;且不会把换行符拿走(遗留在缓冲区中)
  4. cin.getline():读取输入的一行字符,会把换行符拿走并且扔掉
  5. cin.ignore():忽略一个字符
  6. cin.ignore(2):忽略两个字符
  7. cin.peek():将输入的第一个字符查看一眼,再放回缓冲区,可用于判断
  8. cin.putback():将字符放回缓冲区,可用于判断
  9. cin.fail():标志位,0为正常,1为异常:
while(){
	....
	cin.clear();//重置标志位
	cin.sync(); //清空缓冲区
	cout<<"标志位是:"<
3.cout
  1. cout.flush():刷新缓冲区,Linux下有效
  2. cout.put():向缓冲区写字符
  3. cout.write():从buffer中写num个字节到当前输出流中。
  4. cout.width(20);:输出长度为20,不足补空格
  5. cout.fill('* ');//所有的空格处用* 填补
  6. cout.setf(ios::left);:左对齐
  7. cout.unsetf(ios::dec);:卸载十进制
  8. cout.setf(ios::hex);:十六进制
  9. cout.setf(ios::showbase);:强制输出整数的基数
  10. cout.unsetf(ios::hex);:卸载十六进制
  11. cout.setf(ios::oct);:八进制
4. 文件读写
  1. 头文件:#include
  2. 写文件OFS:
ofstream ofs;
ofs.open("./test.txt",ios:out | ios:trunc);
//ofs.is_open();判断能否打开成功
ofs<<"write something here"<
  1. 读文件IFS:
ifstream ifs;
ifs.open("./test.txt",ios:in);
//ifs.is_open();判断能否打开成功

//第一种右移读文件方式,推荐
char buf[1024];
while(ifs>>buf){
	cout<

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


名称栏目:【C++】9.类型转换,c++异常处理,输入输出流-创新互联
浏览地址:http://myzitong.com/article/pdppo.html