C/C++类型转换和异常处理

异常处理

Posted by chensong on 2017-07-03 15::13::57

前言

异常的处理

正文

一,C/C++类型转换, 继承的使用

分为四种类型

  1. static_cast
  2. reinterpret_cast
  3. dynamic_cast 使用在继承中
  4. 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;
}

结语