C++_类型转换

C++_类型转换

1、在C语言中类型装换分为隐式类型转换和显示类型装换
注意:隐式类型装换是编译器自己猜测开发者的意图,显示类型转换也叫作强制类型转换(编译器不能保证安全问题)

//隐式类型转换例子
#include <stdio.h>

int main(int argc, char **argv)
{
	double d = 100.1;
	int i = d;  // double转为int
	char *str = "100ask.taobao.com";
	int *p = str; // char *转为int * //编译会有警告

	printf("i = %d, str = 0x%x, p = 0x%x\n", i, str, p);  //以%x输出的时候编译器期望是一个unsigned int的变量,但是传入的不是的,所以编译器就会隐式转换

	return 0;
}

//显式类型转换例子
#include <stdio.h>

int main(int argc, char **argv)
{
	double d = 100.1;
	int i = d;  // doubleתΪint
	char *str = "100ask.taobao.com";
	int *p = (int *)str; // char *תΪint * 

	printf("i = %d, str = 0x%x, p = 0x%x\n", i, (unsigned int)str, (unsigned int)p);

	return 0;
}

2、C++提供了很多种类型装换
①动态转换、静态转换、重新解析转换(和C语言的显示转换一样)和对const类型转换
②动态类型转换:dynamic_cast
③静态类型转换:static_cast
④重新解析转换:reinterpert_cast
注意:const char *不能直接转化成int *,所以要是用const_cast<char *>()来去掉const属性

#include <stdio.h>

int main(int argc, char **argv)
{
	double d = 100.1;
	int i = d;  // double转换int
	const char *str = "100ask.taobao.com";
	char *str2 = const_cast<char *>(str);  //去掉const属性
	int *p = reinterpret_cast<int *>(str2); // char *转换int *  //相当于C语言风格的用小括号强制类型转换
 
	printf("i = %d, str = 0x%x, p = 0x%x\n", i, reinterpret_cast<unsigned int>(str), reinterpret_cast<unsigned int>(p));

	return 0;
}

3、动态类型转换和静态类型转换
①dynamic_cast<Englishman *>(&h)动态类型转换这个函数就是根据指针找到虚函数表找到类的信息
②动态新型转换只能够用在含有虚函数的类里面
注意:借用之前以人类为基类,然后有中国人和英国人继承人类作为基类

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
	virtual ~Human() { cout<<"~Human()"<<endl; }
	virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
	virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
	virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};

void test_eating(Human& h)
{
	Englishman *pe;
	Chinese    *pc;
	
	h.eating();

	/* 想分辨这个"人"是英国人还是中国人? */
	if (pe = dynamic_cast<Englishman *>(&h))
		cout<<"This human is Englishman"<<endl;

	if (pc = dynamic_cast<Chinese *>(&h))
		cout<<"This human is Chinese"<<endl;
}

int main(int argc, char **argv)
{
	Human h;
	Englishman e;
	Chinese c;

	test_eating(h);
	test_eating(e);
	test_eating(c);

	return 0;
}

4、动态类型转换能不能装换出他的父类呢

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
	virtual ~Human() { cout<<"~Human()"<<endl; }
	virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
	virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
	virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};

class Guangximan : public Chinese {
public:
	void eating(void) { cout<<"use chopsticks to eat, I come from guangxi"<<endl; }
};

void test_eating(Human& h)
{
	Englishman *pe;
	Chinese    *pc;
	Guangximan *pg;
	
	h.eating();

	/* 想分辨这个"人"是英国人还是中国人? */
	if (pe = dynamic_cast<Englishman *>(&h))  //动态类型转换指针
		cout<<"This human is Englishman"<<endl;

	if (pc = dynamic_cast<Chinese *>(&h))  //动态类型转换指针
		cout<<"This human is Chinese"<<endl;
	
	if (pg = dynamic_cast<Guangximan *>(&h))  //动态类型转换指针
		cout<<"This human is Guangximan"<<endl;
}

int main(int argc, char **argv)
{
	//Human h;
	//Englishman e;
	//Chinese c;
	Guangximan g;

	//test_eating(h);
	//test_eating(e);
	//test_eating(c);
	test_eating(g);
	return 0;
}

5、动态类型转换能不能转换引用?
①动态类型转换会根据类信息判断是不是属于类的对象,所以比强制类型转换要安全
注意:是不行的,会导致程序崩溃(引用必须指向一个实体),所以在动态类型转换过程中使用指针而不是使用引用

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
	virtual ~Human() { cout<<"~Human()"<<endl; }
	virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
	virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};

class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
	virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};

class Guangximan : public Chinese {
public:
	void eating(void) { cout<<"use chopsticks to eat, I come from guangxi"<<endl; }
};

void test_eating(Human& h)
{
#if 1
	//Englishman& pe = dynamic_cast<Englishman&>(h);  //动态类型转换引用
	Chinese&    pc = dynamic_cast<Chinese&>(h);      //动态类型转换引用
	Guangximan& pg = dynamic_cast<Guangximan&>(h);  //动态类型转换引用

	h.eating();
}

int main(int argc, char **argv)
{
	//Human h;
	//Englishman e;
	//Chinese c;
	Guangximan g;

	//test_eating(h);
	//test_eating(e);
	//test_eating(c);
	test_eating(g);

	return 0;
}

6、上下行转换

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
	virtual ~Human() { cout<<"~Human()"<<endl; }
	virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
	virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};

class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
	virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};

class Guangximan : public Chinese {
public:
	void eating(void) { cout<<"use chopsticks to eat, I come from guangxi"<<endl; }
};

void test_eating(Human& h)
{
#if 1
	//Englishman& pe = dynamic_cast<Englishman&>(h);  //动态类型转换引用
	Chinese&    pc = dynamic_cast<Chinese&>(h);      //动态类型转换引用
	Guangximan& pg = dynamic_cast<Guangximan&>(h);  //动态类型转换引用
#else
	Englishman& pe = reinterpret_cast<Englishman&>(h);  //强制类型转换
	Chinese&	pc = reinterpret_cast<Chinese&>(h);     //强制类型转换
	Guangximan& pg = reinterpret_cast<Guangximan&>(h);  //强制类型转换
#endif

	h.eating();
}

int main(int argc, char **argv)
{
	Human h;
	//Englishman e;
	//Chinese c;
	Guangximan g;

	Englishman *pe;

	pe = static_cast<Englishman *>(&h);  //下行转换,这个人的类转换成英国人的时候有安全隐患,static_cast是检查不出来的

	//Englishman *pe2 = static_cast<Englishman *>(&g);  //广西人不能够转换成英国人(他们之间没有关系啊),static_cast可以检查出来

	Chinese *pc = static_cast<Chinese *>(&g);  //上行转换,广西人可以上行转换成中国人,因为他们之间有继承关系

	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值