static_cast用法浅析

用法:static_cast < type-id > ( expression )

一般来说,编译器隐式执行的任何类型转换都可以由static_cast显式完成。static_cast可以用来将枚举类型转换成整型,或者整型转换成浮点型。也可以用来将指向父类的指针转换成指向子类的指针。做这些转换前,你必须确定要转换的数据确实是目标类型的数据,因为static_cast不做运行时的类型检查以保证转换的安全性。也因此,static_cast不如dynamic_cast安全。对含有二义性的指针,dynamic_cast会转换失败,而static_cast却直接且粗暴地进行转换,这是非常危险的。

还有要注意的是,他不能转换掉expression的const、volatile、或者__unaligned属性,同样也不能用来去掉static属性。

C++中的static_cast执行非多态的转换,用于代替C中通常的转换操作。对于我们的static_cast转换符,他不仅可以应用到指针和引用上,而且还可以应用到基础数据结构和对象上。

(1)用于基本的数据类型转换(char,int),及指针之间的转换

#include <iostream>
using namespace std;

int main()
{
	char a = 'c';
	int b = static_cast<int>(a);
	char c = static_cast<char>(b);
	cout<<"a= "<<a<<endl;
	cout<<"b= "<<b<<endl;
	cout<<"c= "<<c<<endl;

	char* pa = &a;
	int *pb = (int*)pa;
	//int *pb = static_cast<int*>(pa);   //error
	//pa = static_cast<char*>(pb);   //error
	char *pc = (char*)pb;
	//char *pc = static_cast<char*>(pb);  //error
	cout<<"pa= "<<pa<<endl;
	cout<<"pb= "<<pb<<endl;
	cout<<"pc= "<<pc<<endl;

	void *pd = static_cast<void*>(pa);
	int *pe = static_cast<int*>(pd);
	char *pf = static_cast<char*>(pd);
	cout<<"pd= "<<pd<<endl;
	cout<<"pe= "<<pe<<endl;
	cout<<"pf= "<<pf<<endl;

	system("pause");
	return 0;
}

但是有些情况需要注意的,不然很容易出错,例如:

#include <iostream>
using namespace std;

int main()
{
	int a = 2;
	int b = 3;
	double c,d;
	c = static_cast<double>(a)/b;
	d = static_cast<double>(a/b); //错误
	cout<<"c= "<<c<<endl;
	cout<<"d= "<<d<<endl;
	system("pause");
	return 0;
}

(2)类层次中基类与子类成员函数指针的转换

class A
{
public:
    void set(){}
};
class B:public A
{
public:
    void set(){}
};
typedef void (A::*PS_MFunc)();        //指向类A的成员函数指针
 
PS_MFunc func = &A::set;
func = static_cast<PS_MFunc>(&B::set); //基类指向子类成员函数指针,必须进行转换
(3)类层次结构中基类与子类指针或引用之间的转换

 上行转换:子类指针或引用转换成基类表示——安全

  下行转换:基类指针或引用转换成子类表示——危险(没有动态类型检查)

<span style="font-size:14px;">class A
{
};
class B:public A
{
};
class C:public A
{
};
class D
{
};
A objA;
B objB;
A* pObjA = new A();
B* pObjB = new B();
C* pObjC = new C();
D* pObjD = new D();

objA = static_cast<A&>(objB);     //转换为基类引用    
objA = static_cast<A>(objB);
objB = static_cast<B>(objA);      //error 不能进行转换  

pObjA = pObjB;                    //right 基类指针指向子类对象
//objB = objA;                      //error 子类指针指向基类对象
pObjA = static_cast<A*>(pObjB);   //right 基类指针指向子类
pObjB = static_cast<B*>(pObjA);   //强制转换 OK 基类到子类
//pObjC = static_cast<C*>(pObjB);   //error 继承于统一类的派生指针之间转换 
//pObjD = static_cast<D*>(pObjC);   //error 两个无关联之间转换</span>

最后总结一下:

static_cast常用来进行基本类型直接的转换,如char与int、int与float、enum与int之间;

static_cast也可以转换用户自定义类型,但目标类型必须含有相应的构造函数;

static_cast还可以转换对象的指针类型,但它不进行运行时类型检查,所以是不安全的;

static_cast甚至可以把任何表达式都转换成void类型;

satic_cast不能移除变量的const属性,请参考const_cast操作符;

static_cast进行的是简单粗暴的转换,所以其正确性完全由程序员自己保证。


参考链接:

        http://www.cnblogs.com/pigerhan/archive/2013/02/26/2933590.html

        http://www.cnblogs.com/bastard/archive/2011/12/14/2288117.html

  


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值