C++中4个转换运算符:static_cast/const_cast/dynamic_cast/reinterpret_cast

    转自:http://tianyufeixiang.blog.163.com/blog/static/79370408201071332056265/

    本人没有验证!

     在C中几乎可以将任何类型强制转化成另外一种类型。这点是C的特点,也是C中容易出错的地方,让程序员对转化结果负责。C++除了兼容C强制转换操作符号外还增加了4个类型转化操作符号分别是static_cast、const_cast、dynamic_cast、reinterpret_cast。

static_cast    使用在大多数数据类型转换地方,比如将Unsigned int转化int,一般用于数据类型转化。

const_cast    用于将const类型转化为非const类型。这点属于容易出错的地方,在C中也可以使用强制转换操作符完成这个过程。但const_cast是关键字,在任何编辑器中都很容易找到使用的地方。一旦遇到因为const转换到非const的问题,立即就能够找到转化的地方进行检查调试。而使用C风格的转换符号则比较加难找。一没语法高亮,二没固定字符串可以搜索,三C风格的转换操作符样子都一样不容易区分。容易在出问题的时候快速找到这一个理由足够说服使用 const_cast

dynamic_cast    用于把基类指针或引用转换成派生类的指针或引用。如果在需要用到dynamic_cast的地方使用C风格的转换操作符那就是大错特错了。看以下代码


class A
{
public:
	virtual ~A() {}
};

class B
{
public:
	virtual ~B() {}
};

class C:public A,public B
{
};

class D:public B
{
};

int main( int argc, char* argv[] )
{
	C* p = new C;
	A* pA = p;
	B* pB = p;
	printf( "%p\t%p\t%p\n" , p , pA , pB );
	printf( "%p\t%p\t%p\n" , p , ( C* )pA , ( C* )pB );
	printf( "%p\t%p\t%p\n" , ( D* )p , ( D* )pA , ( D* )pB );//注意这一行
	printf( "%p\t%p\t%p\n" , dynamic_cast<D*>( p ) ,dynamic_cast<D*>( pA ) , dynamic_cast<D*>( pB ) );
	delete p;
	return 0;
}

在我机器上输出如下

00394FD8 00394FD8 00394FDC

00394FD8 00394FD8 00394FD8

00394FD8 00394FD8 00394FDC

00000000 00000000 00000000

在将指针p转化成D*类型的时候使用了2中方法,结果却完全不同。很明显p不是D类型的,转化成D类型应该失败,而C风格却成功了。可以想像这样的代码会带来怎样的隐患

在这里dynamic_cast给出了正确的结果,正是我们所期望的结果。

reinterpret_cast   C类型转化的替代品,功能和C的强制转换操作符号一模一样。即使功能相同,但也应该优先使用reinterpret_cast。因为在编辑器中reinterpret_cast关键字非常醒目,能够时时提醒这是一个需要程序员承担后果的转换。

在C中有一个为了兼容旧代码的规定,那就是char* p=”aa”的合法。在这里将一个const char*类型转化成了char*,本来不合法的事情在这里变成了合法。于是很容易就有人写出类似的代码


int main()
{
	char* p="aaa" ;
	strcpy( p , "bb" );  //原型声明:extern char *strcpy(char *dest,char *src);
                                       //把src所指由NULL结束的字符串复制到dest所指的数组中。
                                       //src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。
	return 0;
}

绝大多数编译器编译这个代码都不会有警告,但运行的时候基本上都会给一个系统异常正确的写法应该是:

int main()
{
	const char* p="aaa" ;
	strcpy( p , "bb" );//编译错误
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值