C++标准转换运算符:static_cast

static_cast <new_type> (expression)

虽然const_cast是用来去除变量的const限定,但是static_cast却不是用来去除变量的static引用。其实这是很容易理解的,static决定的是一个变量的作用域和生命周期,比如:在一个文件中将变量定义为static,则说明这个变量只能在本Package中使用;在方法中定义一个static变量,该变量在程序开始存在直到程序结束;类中定义一个static成员,该成员随类的第一个对象出现时出现,并且可以被该类的所有对象所使用。

对static限定的改变必然会造成范围性的影响,而const限定的只是变量或对象自身。但无论是哪一个限定,它们都是在变量一出生(完成编译的时候)就决定了变量的特性,所以实际上都是不容许改变的。这点在const_cast那部分就已经有体现出来。

static_cast和reinterpret_cast一样,在面对const的时候都无能为力:两者都不能去除const限定。两者也存在的很多的不同,比如static_cast不仅可以用在指针和引用上,还可以用在基础数据和对象上;前面提到过reinterpret_cast可以用在“没有关系”的类型之间,而用static_cast来处理的转换就需要两者具有“一定的关系”了。

还是用例子来说明比较直观一些。

在reinterpret_cast一篇,已经提到过reinterpret_cast可以在任意指针之间进行互相转换,即使这些指针所指的内容是毫无关系的,也就是说一下语句,编译器是不会报错的,但是对于程序来说也是毫无意义可言的,只会造成程序崩溃:

#include <iostream>

using namespace std;

unsigned short Hash( void *p ) {

unsigned long val = reinterpret_cast<unsigned long>( p );

return ( unsigned short )( val ^ (val >> 16));

}

class Something

{

/* Some codes here */

};

class Otherthing

{

/* Some codes here */

};

int main() {

typedef unsigned short (*FuncPointer)( void *) ;

FuncPointer fp = Hash;     //right, this is what we want

int a[10];

const int* ch = a; //right, array is just like pointer

char chArray[4] = {'a','b','c','d'};

fp = reinterpret_cast<FuncPointer> (ch); //no error, but does not make sense

ch = reinterpret_cast<int*> (chArray);  //no error

cout <<hex<< *ch;     //output: 64636261     //it really reinterpret the pointer

Something * st = new Something();

Otherthing * ot = reinterpret_cast<Otherthing*> (st); //cast between objects with on relationship

}

而以上转换,都是static_cast所不能完成的任务,也就是说把上边程序里所有的reinterpret_cast换成static_cast的话,就会立即得到编译错误,因为目标指针和原始指针之间不存在“关系”。

从上边的程序,也就一下子看出来了reinterpret_cast和static_cast之间最本质的区别。

对于static_cast所需要的关系,“继承”绝对是其中之一,所以static_cast支持指向基类的指针和指向子类的指针之间的互相转换:

class Parents

{

public:

virtual ~Parents(){}

/*codes here*/

};

class Children : public Parents

{

/*codes here*/

};

int main()

{

Children * daughter = new Children();

Parents * mother = static_cast<Parents*> (daughter); //right, cast with polymorphism

Parents * father = new Parents();

Children * son = static_cast<Children*> (father); //no error, but not safe

}

但是从基类到子类的转换,用static_cast并不是安全的,具体的问题会在dynamic_cast一篇阐述。

在指针和引用方便,似乎也只有继承关系是可以被static_cast接受的,其他情况的指针和引用转换都会被static_cast直接扔出编译错误,而这层关系上的转换又几乎都可以被dynamic_cast所代替。这样看起来static_cast运算符的作用就太小了。

实际上static_cast真正用处并不在指针和引用上,而在基础类型和对象的转换上。而基于基础类型和对象的转换都是其他三个转换运算符所办不到的。

这些转换跟C++用户自定义类型转换一文中所设计的内容比较接近,所以在那边文章中出现转换可以全部加上static_cast。

基础类型转换:

float floatValue = 21.7;

int intValue = 7;

cout << floatValue / 7 << "\t\t" << static_cast<int> (floatValue)/7 <<endl;

cout << intValue/3 << "\t\t" << static_cast<double> (intValue)/3 << endl;

//Output:

//3.1     3

//2       2.33333

从输出结果可以看出转换是成功并且正确的。

对于对象的转换,也是需要又关系的,这层关系就是C++用户自定义类型转换中提到的方法:

构造函数(Constructor)

类型转换运算符(Type –Cast Operator

static_cast会根据上述顺序寻找到合适的方法进行类型转换。

赋值运算符并不被算在内,因为它自身已经是一种运算符,不能再当做转换运算符来用。

int main(void)

{

Ape a;

Human h = static_cast<Human> (a); // using promtion constructor

Programmer p;

p = static_cast<Programmer> (h); // using  Programmer-cast operaotor

//Ape a2;

//a2 = static_cast<Ape> (p); //Error, assignment operator should be used directly

return 0;

}

(类的代码见C++用户自定义类型转换,或者下载代码查看)

传统转换方式实现static_cast运算符

从上边对static_cast分析可以跟看,static_cast跟传统转换方式几乎是一致的,所以只要将static_cast和圆括号去掉,再将尖括号改成圆括号就变成了传统的显示转换方式。在C++用户自定义类型转换一文已有很多的介绍了。

C++标准转换运算符:static_cast相关推荐

  1. C++标准转换运算符static_cast

    C++标准转换运算符static_cast static_cast <new_type> (expression) 虽然const_cast是用来去除变量的const限定,但是static ...

  2. 【转】C++标准转换运算符static_cast

    static_cast<new_type> (expression) 虽然const_cast是用来去除变量的const限定,但是static_cast却不是用来去除变量的static引用 ...

  3. C 标准转换运算符const_cast

    C++标准转换运算符const_cast 前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述.C++相比于C是一门面向对象的语言,面向对象最大 ...

  4. C++标准转换运算符:const_cast

    C++标准转换运算符:const_cast 前面讲了C++继承并扩展C语言的传统类型转换方式,最后留下了一些关于指针和引用上的转换问题,没有做详细地讲述.C++相比于C是一门面向对象的语言,面向对象最 ...

  5. C++标准转换运算符:dynamic_cast

    C++标准转换运算符:dynamic_cast dynamic_cast <new_type> (expression) dynamic_cast运算符,应该算是四个里面最特殊的一个,因为 ...

  6. C++标准转换运算符:reinterpret_cast

    C++标准转换运算符:reinterpret_cast reinterpret_cast <new_type> (expression) reinterpret_cast运算符是用来处理无 ...

  7. 【C++】C++ 强制转换运算符

    C++ 运算符 强制转换运算符是一种特殊的运算符,它把一种数据类型转换为另一种数据类型.强制转换运算符是一元运算符,它的优先级与其他一元运算符相同. 大多数的 C++ 编译器都支持大部分通用的强制转换 ...

  8. C++类型转换运算符 static_cast,dynamic_cast,reinterpret_cast,const_cast

    类型转换是一种让程序猿可以临时或永久性改变编译器对对象的解释机制.可改变对象解释方式的运算符称为类型转换运算符. 为何须要进行类型转换 通常为了实现使用不同环境的个人和厂商编写的模块可以相互调用和协作 ...

  9. C++核心准则C.164:避免隐式转换运算符

    C.164: Avoid implicit conversion operators C.164:避免隐式转换运算符 Reason(原因) Implicit conversions can be es ...

最新文章

  1. 微软向马斯克的人工智能公司OpenAI投资10亿美元
  2. Python编程基础:第二节 多重赋值Multiple Assignment
  3. [原创]Synergy安装方法
  4. 【NLP】中文BERT上分新技巧,多粒度信息来帮忙
  5. Oracle自定义聚集函数
  6. 2019年的第三场LiveVideoStackCon有何不同?
  7. 同方挑战惠普 大打“惠民”牌
  8. 做风控的你,GPS数据有没有这样用?
  9. leetcode力扣64. 最小路径和
  10. 关于bacula网络备份软件的安装以及配置1
  11. 通过HttpModule实现IP地址屏蔽功能
  12. 关于机器学习的十个实例
  13. Android页面传值b,android数据传递(一)之activityA传递到activityB
  14. 锐捷客户端登陆打不开网页
  15. Win 10间歇性卡顿问题
  16. STM32驱动NRF24L01无线模块
  17. 核酸检测系统的潜在性能问题猜想
  18. 严寒冰 国家计算机网络,北京航空航天大学计算机学院——严寒冰
  19. java中principal对象,如何使用OAuth2获取Spring的自定义Principal对象?
  20. laravel validate 验证器

热门文章

  1. Linux 命令(92)—— locate 命令
  2. C++ 数据类型转换详解之终极无惑
  3. Spring通过注解装配Bean
  4. win7 vmware ubuntu16 xshell链接
  5. [转载] 高级人工智能——第3章 约束推理
  6. HDU-1358 Period KMP
  7. 智能交通|智慧产业园区管理系统集成搭建
  8. kernel笔记——库文件与系统调用
  9. PHP执行耗时脚本实时输出内容
  10. 用 ReactJs 创建Mac版的 keep