C++提高 09(类型转换,yichan)

本文详细介绍了C++中的不同类型转换方式,包括隐式类型转换、显式类型转换、static_cast、dynamic_cast、reinterpret_cast及const_cast,并通过实例演示了它们的应用场景。此外,还探讨了C++中的异常处理机制,包括如何抛出和捕获不同类型的异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.类型转换

#include<iostream>
using namespace std;

void main()
{
	double pai = 3.1415926;
	int num01 = pai;//c语言的隐式类型转换;
	int num03 = static_cast<int>(pai);//c语言中的隐式类型转换 均可使用static_cast<>进行转换;
	int num02 = (int)pai;//显示类型转换
	cout << num02 << endl;

	char* p = "hello...C++";
	int* i = NULL;
	i =reinterpret_cast<int *> (p);//如果不同类型之间进行类型转换的时候,需要使用reinterpret_cast<>;

	cout << i << endl;//相当于打印的%d;
	cout << p << endl;//打印的是%s;
	
	system("pause");
}
对象进行类型转换:

#include<iostream>
using namespace std;


class Anima 
{
public:
	virtual void eat()
	{
		cout << "动物吃饭" << endl;
	}
};
class Dog : public Anima
{
public :
	
	void kanmen()
	{
		cout << "狗看门" << endl;
	}
};

void test(Anima * a)
{
	//这种转型必须条件是有虚函数,发生多态;
	Dog* dd = dynamic_cast<Dog*>(a);
	dd->eat();
	dd->kanmen();

	Dog* dd2 = reinterpret_cast<Dog*>(a);//强制类型转换,类型从新解释;
	dd2->eat();
	dd2->kanmen();

	//编译进行类型检查,Anima和Dog是一个家族的可以转换;
	//如果在定义个Tree类对象,使用static_cast进行tree转换成dog就会报错;
	Dog* dd3 = static_cast<Dog*>(a);
	dd3->eat();
	dd3->kanmen();
}
void main()
{
	double pai = 3.1415926;
	int num01 = pai;//c语言的隐式类型转换;

	//c语言中的隐式类型转换 均可使用static_cast<>进行转换;在编译的时候进行类型检查;
	int num03 = static_cast<int>(pai);
	int num02 = (int)pai;//显示类型转换
	cout << num02 << endl;

	char* p = "hello...C++";
	int* i = NULL;
	i =reinterpret_cast<int *> (p);//如果不同类型之间进行类型转换的时候,需要使用reinterpret_cast<>;

	cout << i << endl;//相当于打印的%d;
	cout << p << endl;//打印的是%s;

	//当子父类之间进行类型转换的时候:dynamic_cast;
	Dog d;
	test(&d);

	system("pause");
}

const_cast:的使用

#include<iostream>
using namespace std;

void test(const char* p)
{
	//将只能读的指针转换成可以读写的指针;
	char* m = const_cast<char *>(p);
	m[0] = 'Z';
	cout << m << endl;
}
void main()
{
	//将常量区的字符串拷贝到栈区,动态分配内存;
	char c[] = "abcdefghijklmnopqrstuvwxyz";
	test(c);

	//这个是一个指针直接指向一个常量区的字符串;不能修改的;
	//char* mm= "abcdefghijklmnopqrstuvwxyz";
	//test(mm);//这样就会报错;
	system("pause");
}

结论:程序员要清楚的知道:要转换的变量,类型转换之前和之后的类型,转后的后果是什么;

 一般情况下不建议类型转换,避免类型转换;


2.C++中的异常:

#include<iostream>
using namespace std;

//返回int类型的异常
void copychar(const char* str1, char* str2)
{
	if (str1==NULL)
	{
		throw 1;
	}
	if (str2 == NULL)
	{
		throw 2;
	}
	if (*str1 == 'z')
	{
		throw 3;
	}

	while (*str1 !='\0')
	{
		*str2 = *str1;
		str1++;
		str2++;
	}
	*str2 = '\0';
}

//抛出char* 类型的异常;
void copychar2(const char* str1, char* str2)
{
	if (str1 == NULL)
	{
		throw "str1 = null";
	}
	if (str2 == NULL)
	{
		throw "str2 = null";
	}
	if (*str1 == 'z')
	{
		throw "拷贝过程中出错了";
	}

	while (*str1 != '\0')
	{
		*str2 = *str1;
		str1++;
		str2++;
	}
	*str2 = '\0';
}

class Str1 {};
class Str2 {};
class CopyErr {};

//抛出对象 类型的异常;
void copychar2(const char* str1, char* str2)
{
	if (str1 == NULL)
	{
		throw Str1();
	}
	if (str2 == NULL)
	{
		throw Str2();
	}
	if (*str1 == 'z')
	{
		throw CopyErr();
	}

	while (*str1 != '\0')
	{
		*str2 = *str1;
		str1++;
		str2++;
	}
	*str2 = '\0';
}

void main()
{

	char str[] = "zbcdefg";
	char str2[500];

	try
	{
		//copychar(str,str2);
		copychar2(str, str2);
	}
	catch (int e)//e可以写也可以不写,就看你用不用这个e;
	{
		cout << e << "int 类型数据异常" << endl;
	}
	catch (char* c)
	{
		//char* c所指向的内存空间是在throw的时候分配的内存的;
		cout << c << "char* 类型数据异常" << endl;
	}
	//-----------
	catch (Str1 s)
	{
		//这种是将匿名对象拷贝给s的;
		cout << "Str1 类型数据异常" << endl;
	}
	catch (Str2* s2)
	{
		//这种情况就接受不到异常了,上面发的是对象异常,这里用指针接受不到的;会调到位置异常中去;
		//异常时严格的按照类型匹配的,如果非要用指针接的话,throw的时候必须抛出一个地址,
		//但是还不能是内名对象,因为会被析构掉,成为野指针,必须是new出来的对象;new的实在堆中分配的内存,需要手动许释放内存的;
		cout << "Str2 类型数据异常" << endl;
	}
	catch (CopyErr& cs)
	{
		//这种事将对象直接扔过的;所以在抛出一个对象异常的时候,使用引用接受是最好的;
		cout << "CopyErr 类型数据异常" << endl;
	}
	//-----------
	catch (...)
	{
		cout << "位置 类型数据异常" << endl;
	}
	system("pause");
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值