WHCSRL 技术网

【C++】强制类型转换操作符 static_cast

参考:

  1. https://www.cnblogs.com/QG-whz/p/4509710.html
  2. https://blog.csdn.net/moruihong/article/details/7712260

一、简介:

  • static_cast是一个强制类型转换操作符。强制类型转换,也称为显式转换,C++中强制类型转换操作符有static_cast、dynamic_cast、const_cast、reinterpert_cast四个

  • 用法:static_cast < type-id > ( expression )
    该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。

二、使用:

  1. 编译器隐式执行的任何类型转换都可以由static_cast来完成,比如int与float、double与char、enum与int之间的转换等。
double a = 1.999;
int b = static_cast<double>(a); //相当于a = b ;
  • 1
  • 2

当编译器隐式执行类型转换时,大多数的编译器都会给出一个警告:

e:vs 2010 projectsstatic_caststatic_caststatic_cast.cpp(11): warning C4244: “初始化”: 从“double”转换到“int”,可能丢失数据
  • 1

使用static_cast可以明确告诉编译器,这种损失精度的转换是在知情的情况下进行的,也可以让阅读程序的其他程序员明确你转换的目的不是由于疏忽。
  
把精度大的类型转换为精度小的类型,static_cast使用位截断进行处理。

  1. 使用static_cast可以找回存放在void*指针中的值。
double a = 1.999;
void * vptr = & a;
double * dptr = static_cast<double*>(vptr);
cout<<*dptr<<endl;//输出1.999
  • 1
  • 2
  • 3
  • 4
  1. static_cast也可以用在于基类与派生类指针或引用类型之间的转换。
    然而它不做运行时的检查,不如dynamic_cast安全。static_cast仅仅是依靠类型转换语句中提供的信息来进行转换,而dynamic_cast则会遍历整个类继承体系进行类型检查,因此dynamic_cast在执行效率上比static_cast要差一些。现在我们有父类与其派生类如下:
class ANIMAL
{
public:
    ANIMAL():_type("ANIMAL"){};
    virtual void OutPutname(){cout<<"ANIMAL";};
private:
    string _type ;
};
class DOG:public ANIMAL
{
public:
    DOG():_name("大黄"),_type("DOG"){};
    void OutPutname(){cout<<_name;};
    void OutPuttype(){cout<<_type;};
private:
    string _name ;
    string _type ;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

此时我们进行派生类与基类类型指针的转换注意!!!从下向上的转换是安全的,从上向下的转换不一定安全。

int main()
{
    //基类指针转为派生类指针,且该基类指针指向基类对象。
    ANIMAL * ani1 = new ANIMAL ;
    DOG * dog1 = static_cast<DOG*>(ani1);
    //dog1->OutPuttype();//错误,在ANIMAL类型指针不能调用方法OutPutType();在运行时出现错误。

    //基类指针转为派生类指针,且该基类指针指向派生类对象
    ANIMAL * ani3 = new DOG;
    DOG* dog3 = static_cast<DOG*>(ani3);
    dog3->OutPutname(); //正确

    //子类指针转为派生类指针
    DOG *dog2= new DOG;
    ANIMAL *ani2 = static_cast<DOG*>(dog2);
    ani2->OutPutname(); //正确,结果输出为大黄

    //
    system("pause");

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  1. static_cast可以把任何类型的表达式转换成void类型
  2. 另外,与const_cast相比,static_cast不能换掉变量的const属性,也包括volitale或者__unaligned属性。

总结:

  • ①用于类层次结构中基类(父类)和 派生类(子类)之间指针或引用的转换。
      进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;
      进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的。
  • ②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
  • ③把空指针转换成目标类型的空指针。
  • ④把任何类型的表达式转换成void类型。

C++中static_cast和 reinterpret_cast的区别:

编译器隐式执行任何类型转换都可由static_cast显示完成;reinterpret_cast通常为操作数的位模式提供较低层的重新解释:

  1. C++中的static_cast执行非多态的转换,用于代替C中通常的转换操作。因此,被做为隐式类型转换使用。比如:
int i;
float f = 166.7f;
i = static_cast<int>(f);
  • 1
  • 2
  • 3

此时结果,i的值为166。

  1. C++中的reinterpret_cast主要是将数据从一种类型转换为另一种类型。所谓“通常为操作数的位模式提供较低层的重新解释”也就是说将数据以二进制存在形式的重新解释。比如:
int i;
char *p = "This is a example.";
i = reinterpret_cast<int>(p);
  • 1
  • 2
  • 3

此时结果,i与p的值是完全相同的。reinterpret_cast的作用是说将指针p的值以二进制(位模式)的方式被解释为整型,并赋给i。 i 也是指针,整型指针;一个明显的现象是在转换前后没有数位损失。

推荐阅读