异常:程序员写代码的时候预料道有可能出问题,但没有办法避免。
异常处理:
- C的异常处理:全部依赖函数返回值
- C++异常处理方式:C++完全兼容C的异常处理方式,但是它还多出来一些异常处理方式
C++的异常处理关键字:try catch(try和catch搭配使用) throw抛(可以单独去用)
try{//包含一段代码
}catch()//抓取try包含代码段中抛出的异常
C++的异常处理机制:
- try里面出的问题,catch来处理。
- try外面出的问题,归由上一层来处理。如果一直处理不了,直接调用abort中断。
- 异常处理一去不回头
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
int m=10;
try{
int i=1;
char name[20]="newer";
cout<<"背起背包走天下"<<endl;
throw i;//异常就是一个变量,类似于函数的返回值
cout<<"继续浪荡天涯"<<endl;
throw name;
cout<<"走遍天下锦衣归家"<<endl;
}
catch(int n){//可以理解成一个函数
cout<<"抓到一个异常"<<n<<endl;
}//如果抛出来的异常无人抓取就会调用abort中断
cout<<"小样,给老婆跪搓衣板去" <<endl;
while(1);
return 0;
}
#include <iostream>
using namespace std;
#include <cstring>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
class MyExcept{
char buff[256];
public:
MyExcept(){strcpy(buff,"自定义异常类型"); }
char* getBuff(){return buff;
}
};
void f(int n){//最底层
if (n==10) throw n;
if(n==20) throw 3.1415;
if(n==30) throw 1.11f;
cout<<"最底层执行了"<<endl;
}
void ctrData(){
int val;
cout<<"ctrData中请输入整数";
cin>>val;
if(val==0)throw"value==0";
try{
if(val<-50){
MyExcept e;
throw e;
}
if(val>50){
throw "val>50";
}else{
f(val);
}
}
catch(int i){
cout<<"中间层第一级"<<i<<endl;
}
catch(char*str){
cout<<"中间层第一级"<<str<<endl;
}
catch(float f){
cout<<"中间层第三级"<<f<<endl;
}
cout<<"中间层执行了";
}
int main(int argc, char** argv) {
try{
ctrData();
cout<<"最高层执行了"<<endl;
}
catch(char*str){
cout<<"最高层第一级:"<<str<<endl;
}
catch(MyExcept& e){
cout<<"最高层第二级"<<e.getBuff()<<endl;
}
catch(...){//匹配任意类型
cout<<"最终处理方式:"<<endl;
}
cout<<"最高层之后做啥"<<endl;
while(1);
return 0;
}
C++标准异常类:
基类:exception(C++所有的异常处理类都是该类的派生类)
派生类:bad_alloc
#include <iostream>
#include <stdexcept>//C++标准异常类头文件
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
class A{
int arr[10000];
};
int main(int argc, char** argv) {
try{
while(1){
A* p=new A;
//每new一个对象就是40000字节(大约40K),堆内存总有完的时候x86window操作系统堆内存一般2G
}
}catch(bad_alloc& a){
cout<<"抓到内存开辟异常"<<endl;
}
cout<<"程序继续运行"<<endl;
return 0;
}
C++11新标准:
#include <iostream>
#include <string>
using namespace std;
int add(int a,int b){
return a+b;
}
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int main(int argc, char** argv) {
//1.定义变量可以用{}
int n=10;//C的用法
int m(11);//C++的用法,就是调用了m的构造函数
int k{12};
int i{1},j{(int)1.1};
cout<<m<<endl;
cout<<k<<endl;
cout<<i<<endl<<j<<endl;
//2.空指针
int*p=NULL;
// int*pn=nullptr;
//3.auto 缺省类型 C中作为存储类型存在 int n 默认为是 atuo int n 但是C++11中auto本身就是一种数据类型
auto i=1;//int i=1;
auto j=6.6;//double j=6.6;
auto n=1;m=1.1;//error
auto k=&i;//建议不要这样写auto* k=&i可读性更好
//当我们不知道一个函数的返回类型的时候,用auto最好用
//4 decltype将变量的声明认定为表达式指定的类型
int i=1;
decltype(i) j=666;
decltype(add(int a,int b)) rec;
decltype((i))k=j;//int&k=j;
k=999;
cout<<j<<endl;
//5 for循环的另外方式 shell 脚本 python
string str="absdseeggg";
char* str="abcdefg";
for(char c:str)
cout<<c<<" ";
cout<<endl;
//6给类型起别名:
typedef int(*Func)(int,int)//*FUnc 就是函数类型
int n;
typedef int INT;
using myINT=int;
using MyFunc=int(*) (int,int)
MyFunc p=add;
cout<<p(1,2)<<endl;
//7在类中使用default关键字,缺省定义构造函数
class A{
int n;
public:
A()=default;
//A(){n=0;}
}
//8 在类中直接初始化
class A{
int n=777;
};
//9构造函数委托
class A{
int n;
public:
A(int n):n(n){
}
};
class B:public A{
public:
B(int nn):A(nn){}
};
class C{
int n;
public:
C(int n):n(n){cout<<"有参构造"<<endl;}
C():C(n){cout<<"无参构造,委托给有参构造"<<endl;}
//吃饱了撑的
//10 final禁止重写
class A{
int n;
public:
A(int n):n(n){ }
virtual void show() final {cout<<"基类A中的n:"<<n<<endl; }
};
class B:public A{
public:
void show(){cout<<"B类中重写的show函数"<<endl; }
return 0;
}