关闭

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

1847人阅读 评论(0) 收藏 举报
分类:

    看过好多次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上的实验结果和看到的资料不一致。有待继续研究。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    About Me
    个人资料
    • 访问:373503次
    • 积分:6831
    • 等级:
    • 排名:第3367名
    • 原创:320篇
    • 转载:0篇
    • 译文:2篇
    • 评论:35条
    博客专栏
    最新评论