static_cast运算符
表达式 static_cast < type-id > ( expression ) 把expression转换为基于expression类型的另外一个类型type-id。转换时不进行运行时类型检查来确保安全性。
语法
static_cast < type-id > ( expression )
static_cast运算符可以进行类似这样的操作:把一个基类指针转换为派生类指针。这样的转换并不总是安全的,比如:
- class B { ... };
- class D : public B { ... };
- void f(B* pb, D* pd)
- {
- D* pd2 = static_cast<D*>(pb); // 不安全, pb可能只是指向B
- B* pb2 = static_cast<B*>(pd); // 安全转换
- ...
- }
和dynamic_cast不同的是,在对pb进行static_cast转换时不进行运行时类型检查。pb指向的对象可能不是类D的一个对象,这种情况下,使用*pd2很可能造成灾难。比如,调用了一个类D的成员函数,而这个函数不是类B的成员函数,将导致访问冲突。
dynamic_cast和static_cast运算符沿着类的层次结构来移动一个指针。然而,static_cast只依赖cast声明中提供的信息,因此不安全。比如:
- class B { ... };
- class D : public B { ... };
- void f(B* pb)
- {
- D* pd1 = dynamic_cast<D*>(pb);
- D* pd2 = static_cast<D*>(pb);
- }
如果pb真的指向类D的一个对象,那么pd1和pd2将得到相同的值。如果pb == 0,他们的值也将相同。
如果pb指向了类B的一个对象,它不是一个完整的D类,那么dynamic_cast会懂得返回一个0值。然而,static_cast依赖于程序员的断言,即pb指向了类D的一个对象,并且简单地返回一个指向假定的D对象的指针。
因此,static_cast可以做反向的强制转换,这种情况下结果是不明确的。确保static_cast转换结果的安全这个任务就留给了程序员来做。
这种行为同样适用于除了类类型转换外的其他类型转换。比如,static_cast可以用来把一个int转换为char。然而做为转换结果的char可能没有足够的二进制位来保存int的值。同样的,确保static_cast转换结果的安全这个任务就留给了程序员来做。
static_cast运算符同样能用于实现任何强制转换,包括标准的转换和用户自定义的转换。比如:
- typedef unsigned char BYTE
- void f()
- {
- char ch;
- int i = 65;
- float f = 2.5;
- double dbl;
- ch = static_cast<char>(i); // int to char
- dbl = static_cast<double>(f); // float to double
- ...
- i = static_cast<BYTE>(ch);
- ...
- }
static_cast运算符能够明确地把一个整形值转换为枚举类型。如果整形值不在枚举值的范围之内,转换得到的枚举值也是不确定的。
static_cast运算符可以把一个空指针转换为目标类型的空指针。
static_cast运算符可以明确地把一个表达式转换为void类型。这个void类型可以包括const,volatile或者__unaligned属性。
static_cast运算符不能够抛弃const,volatile,或者__unaligned属性,可以查看const_cast运算符的说明中关于移除这些属性的信息。
c++, 类型转换, dynamic cast, static cast