前言
C++中异常的处理
正文
一,C/C++类型转换, 继承的使用
分为四种类型
- static_cast
- reinterpret_cast
- dynamic_cast 使用在继承中
- const_cast 改数值的
下面是具体的使用情况
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
class Animal
{
public:
Animal()
{}
~Animal()
{}
virtual void cry() = 0;
private:
};
class Dog : public Animal
{
public:
virtual void cry()
{
cout << "dkfdk" << endl;
}
void doHome()
{
cout << "2222222" << endl;
}
};
class Cat : public Animal
{
public:
virtual void cry()
{
cout << "333" << endl;
}
void doHome()
{
cout << "Cat " << endl;
}
};
void playOBj(Animal *base)
{
base->cry(); // 有继承, 和多态
//C++的类型的识别
//dynamic_cast 运行时类型识别
Dog *pDog =dynamic_cast<Dog *>(base);
if (pDog != NULL)
{
pDog->doHome(); //dog的工作
}
Cat *pCat = dynamic_cast<Cat *>(base);
if (pCat != NULL)
{
pCat->doHome();
}
}
void printBuf(const char *p)
{
char *p1 = NULL;
p1 = const_cast<char *>(p);
p1[0] = 'Z';
cout << p << endl;
}
int main(void)
{
double dp1 = 3.1415926;
//C类型转换
int num = (int)dp1;
//C++静态类型转换 编译的时
int num2 = static_cast<int>(dp1);
int num3 = dp1; //C语言中 隐式转换 都可以使用static_cast转换
//char* ====> int*
//C++ reinterpret_cast 不同类型的转换
char *p1 = "hello world !";
int *p2 = NULL;
p2 = reinterpret_cast<int *>(p1);
cout << "p1: " << p1 << endl;
cout << "p2: " << p2 << endl;
//总结:通过上面C类型转换的替代了
//C++
Cat c; //向下转型
playOBj(&c);
//buf必须是可改的 数组的
char buf[] = "chenli";
printBuf(buf);
printf("\n");
system("pause");
return 0;
}
二,异常处理的
1, 异常的按照类型补获得
(…) 这个是获取所有的异常
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
void mycatch(int x, int y)
{
if (y == 0)
{
throw y;
}
cout << x / y << endl;
}
void myDirde(int x,int y)
{
mycatch(x, y);
}
int main(void)
{
try
{
mycatch(4, 4);
mycatch(4, 0);
}
catch (int e)
{
cout << "0错误" << endl;
}
catch (...)
{
cout << "程序错误" << endl;
}
printf("\n");
system("pause");
return 0;
}
三 ,异常接口声明
1,抛出int,char类型的异常
void fcun() throw (int , char){}
2,抛出所有类型异常
void fcun() throw(){}
3, throw “抛出char类型异常”
结论1,:如果 接受异常的时候, 使用一个异常变量, copy构造异常变量
结论2,使用引用的话 throw时候的那个对象
结论3:指针可以和引用/元素写在一块 , 但是引用和元素不能一起使用
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
//重点异常处理
class BadSrcType {};
class BadDecType {};
class BadProcessType
{
public:
BadProcessType()
{
cout << "1111" << endl;
}
BadProcessType()
{
cout << "~~~~~~~~~1111";
}
};
int my_strcpy(char *tc, char *from)
{
if (from == NULL)
{
//异常处理
throw BadProcessType();
}
if (tc == NULL)
{
return 2;
}
if (*from == 'a')
{
return 3;
}
while (*from != '\0')
{
*tc = *from;
tc++;
from++;
}
return 0;
}
int main(void)
{
int ret = 0;
char buf1[] = "dfd";
char buf2[1024];
ret = my_strcpy(buf2, buf1);
if (ret != 0)
{
switch (ret)
{
case 1:
cout << "buf1错误" << endl;
break;
case 2:
cout << "buf2 错误" << endl;
break;
case 3:
cout << "未知错误" << endl;
break;
default:
break;
}
}
printf("\n");
system("pause");
return 0;
}
四 ,异常在框架的使用案例
内部类的使用
没有优化的代码
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
class MyArray
{
public:
MyArray(int len);
int& operator[](int index);
int getLen();
~MyArray();
//内部类 异常处理
class eNegative {};
class eZero{};
class eTooBig {};
class eTooSmall {};
class eSize {};
private:
int *m_space;
int m_len;
};
MyArray::MyArray(int len)
{
if (len < 0)
{
throw eNegative(); // 抛出异常
}
else if (len == 0)
{
throw eZero();
}
else if (len > 1000)
{
throw eTooBig();
}
else if (len < 3)
{
throw eTooSmall();
}
this->m_len = len;
this->m_space = new int[len];
}
int & MyArray::operator[](int index)
{
return m_space[index];
}
int MyArray::getLen()
{
return this->m_len;
}
MyArray::~MyArray()
{
if (this->m_space != NULL)
{
delete[] this->m_space;
this->m_space = NULL;
this->m_len = 0;
}
}
int main(void)
{
try
{
MyArray a(5);
MyArray b(-5);
int i;
for (i = 0; i < a.getLen(); i++)
{
a[i] = i + 1;
printf("%d\n", a[i]);
}
}
catch (MyArray::eNegative e) //类内类
{
cout << "eNegative 异常" << endl;
}
catch (MyArray::eSize e) //类内类
{
cout << "eSize 异常" << endl;
}
catch (MyArray::eTooBig e) //类内类
{
cout << "eTooBig 异常" << endl;
}
catch (MyArray::eTooSmall e) //类内类
{
cout << "eTooSmall 异常" << endl;
}
catch (MyArray::eZero e) //类内类
{
cout << "eZero 异常" << endl;
}
catch (...)
{
cout << "..." << endl;
}
printf("\n");
system("pause");
return 0;
}
优化后
加入多态的继承的使用
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
using namespace std;
class MyArray
{
public:
MyArray(int len);
int& operator[](int index);
int getLen();
~MyArray();
//内部类 异常处理 继承
class eSize
{
public:
eSize(int size)
{
this->m_size = size;
}
virtual void printErr()
{
cout << "eSize--->size:" << this->m_size << " ";
}
protected:
int m_size;
};
class eNegative : public eSize
{
public:
eNegative(int size) :eSize(size)
{
}
virtual void printErr()
{
cout << "eNegative--->size:" << this->m_size << " ";
}
};
class eZero : public eSize
{
public:
eZero(int size) :eSize(size)
{
}
virtual void printErr()
{
cout << "eZero--->size:" << this->m_size << " ";
}
};
class eTooBig : public eSize
{
public:
eTooBig(int size) :eSize(size)
{
}
virtual void printErr()
{
cout << "eTooBig--->size:" << this->m_size << " ";
}
};
class eTooSmall : public eSize
{
public:
eTooSmall(int size) :eSize(size)
{
}
virtual void printErr()
{
cout << "eTooSmall-->size:" << this->m_size << " ";
}
};
private:
int *m_space;
int m_len;
};
MyArray::MyArray(int len)
{
if (len < 0)
{
throw eNegative(len); // 抛出异常
}
else if (len == 0)
{
throw eZero(len);
}
else if (len > 1000)
{
throw eTooBig(len);
}
else if (len < 3)
{
throw eTooSmall(len);
}
this->m_len = len;
this->m_space = new int[len];
}
int & MyArray::operator[](int index)
{
return m_space[index];
}
int MyArray::getLen()
{
return this->m_len;
}
MyArray::~MyArray()
{
if (this->m_space != NULL)
{
delete[] this->m_space;
this->m_space = NULL;
this->m_len = 0;
}
}
int main(void)
{
try
{
MyArray a(5);
MyArray b(-5);
int i;
for (i = 0; i < a.getLen(); i++)
{
a[i] = i + 1;
printf("%d\n", a[i]);
}
}
//多态的使用 MyArray::eSize &e
catch (MyArray::eSize &e)
{
cout << "len的大小" << endl;
e.printErr();
}
catch (...)
{
cout << "..." << endl;
}
printf("\n");
system("pause");
return 0;
}
五, C++中库文件的异常处理
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
//C++异常处理库
#include <stdexcept>
using namespace std;
class Myexception : public exception
{
public:
Myexception(const char *p) :exception(p)
{
this->p = p;
}
virtual const char * what()
{
return p;
}
private:
const char *p;
};
void setAge(int age)
{
if (age > 100)
{
throw out_of_range("您输入的年龄太大!!!");
}
}
int main(void)
{
try
{
setAge(111);
}
catch (out_of_range e)
{
cout << e.what() << endl;
}
//2,
try
{
throw Myexception("ckfjdkdkf");
}
catch (exception &e)
{
cout << e.what() << endl;
}
catch (...)
{
cout << "chnfd throw " << endl;
}
printf("\n");
system("pause");
return 0;
}