C和C++语言的强制类型转换 Type Cast

    看过好多次C和C++的类型转换的介绍,但总是记不住,再次提起时又会想不起来。主要是因为不常用到的缘故吧。特意写成一篇博客来,总结一下。

与强制类型转换相对应的是自动类型转换。或者强制类型转换叫显示类型转换,自动类型转换叫隐式类型转换。

    自动类型转换会在赋值运算、混合运算、参数传递、返回函数返回值、格式化输出时且当类型出现不一致时发生,转换按数据长度增加的方向进行。

    如果不希望一个类型按照自动类型转换的原则发生变化,就需要使用强制类型转换。


C语言的强制类型转换

    C语言的强制类型转换很简单,不管什么类型的转换统统是,在要转换的变量前面加小括号,里面写上要转换为的类型。

如,TYPE b = (TYPE)a


C++语言的强制类型转换

C++语言中提供了4种强制类型转换操作符来应对不同场合的应用。

static_cast,从命名上理解是静态类型转换。如int转换成char。

dynamic_cast,从命名上理解是动态类型转换。如子类和父类之间的多态类型转换。

const_cast,从命名上理解就是去除变量的const属性。

reinterpreter_cast,仅仅重新解释类型,但没有进行二进制的转换。

四种操作符的使用方法一致:TYPE B = static_cast<TYPE>(a)


static_cast的用法

其作用和C语言中的类型转换作用一致,属于静态的类型转换。


dynamic_cast的用法

其主要用于基类和派生类之间的动态的类型转换。且仅适用于出现virtual的情况。

假如有一个指向派生类对象的基类指针p(这是多态的基础)。

现在要让一个派生类指针去指向p所指的派生类对象。

    若不进行强制类型转换,编译会出错。

    若使用static_cast进行静态转换,可以,但不推荐这样转换。

    若使用dynamic_cast进行动态转换,可以,这是推荐的做法。


假如有一个指向基类对象的基类指针q。

现在要让一个派生类指针去指向q所指的基类对象。

    若不进行强制类型转换,编译会出错。

    若使用static_cast进行静态转换,这时候我发现,原基类对象被扩展为了派生类对象。这和我之前看到的资料说的不一样,之前看到的资料显示,static_cast并不会扩展基类。

    若使用dynamic_cast进行动态转换,这样转换完之后会返回NULL,即转换不成功。

比如:

#include<stdio.h>

void main()
{
	class Base
	{
		public:
			Base():xxx(5)
			{}
			int xxx;
			virtual void foo()
			{}
	};

	class Derived: public Base
	{
		public:
			Derived():yyy(6)
			{}
			int yyy;
			void fun()
			{
				printf("fun\n");
			}
	};

	Base *p = new Derived();
	//Derived *p1 = p; //错误
	//Derived *p1 = static_cast<Derived*>(p); 
	Derived *p1 = dynamic_cast<Derived*>(p);

	Base *q = new Base();
	//Derived *q1 = q; //错误
	Derived *q1 = static_cast<Derived*>(q);
	//Derived *q1 = dynamic_cast<Derived*>(q); q1会是NULL
	
	(*q1).xxx = 100;
	(*q1).yyy = 200;
	(*q1).fun();
	(*q).xxx = 300;
	printf("%d %d %d\n",(*q).xxx,(*q1).xxx,(*q1).yyy);
}

const_cast的用法

    如果const类型的变量直接赋给非const变量,不需要类型转换,后者直接就是非const类型的。const_cast一般是要转换指向const的指针或引用类型,从而能修改const类型变量的值。

比如,

void main()
{
	class A
	{
		public:
			A():xxx(5)
			{}
			int xxx;
	};
	const A a;

	A &b = const_cast<A&>(a);
	b.xxx = 6;

	printf("a = %d\n",a.xxx);
	printf("b = %d\n",b.xxx);
}

reinterpreter_cast的用法

    这种强制转换方式仅仅重新解释类型,不进行实质二进制的转换。转换的类型必须是一个指针、引用、算术类型、函数指针或者成员指针。最普通的用途就是在函数指针类型之间进行转换。

比如,

#include<stdio.h>

int fun1()
{
	printf("fun1\n");
	return 1;
}

void main()
{
	typedef void(*FunPtr)();//函数指针
	FunPtr a;
	//a = &fun1; //错误
	a = reinterpret_cast<FunPtr>(&fun1);
	a();
}


PS遗留问题:

用static_cast将基类指针转换为派生类指针的时候,我在VS2010上的实验结果和看到的资料不一致。有待继续研究。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值