当前课程知识点:基于Linux的C++ >  第十一讲 泛型编程 >  11.6 运行期型式信息(二) >  LinuxCPP1106

返回《基于Linux的C++》慕课在线视频课程列表

LinuxCPP1106在线视频

LinuxCPP1106

下一节:LinuxCPP1107

返回《基于Linux的C++》慕课在线视频列表

LinuxCPP1106课程教案、知识点、字幕

第二个关键字就是 static_cast

它完成静态转型

static_cast 完成静态转型

与 dynamic_cast 不一样

static_cast 它不仅可以用于指针和引用

还可以用于普通的型式

你比如说 int、double

这都可以用

static_cast 一般用于非类型式的普通数据对象的转型动作

static_cast 一般用于非类型式的普通数据对象的转型动作

当然并不是说 static_cast 这个关键字

不能用于类对象的转型动作

它一样可以用于

但是你要记住 static_cast 这个关键字

不管用于非类型式的对象转型

还是类对象的转型

它们都不进行运行期的型式检查

它是不安全的

如果转型失败 结果是无定义的

就是结果是未知的

使用的时候要非常小心

static_cast 和 dynamic_cast 一样

可以在类的继承层次上向上或向下转型

交叉转型呢 不是不可以

但是出错的概率非常非常高

我们一般不用

第三个关键字就是 const_cast

它叫常量转型

常量转型的唯一一个目的

是为了设置量的 const 状态

有的量以前是 const

我想临时修改一下它的内容

那么这个时候就需要一次 const_cast

这样的一次常量转型

如果有的量一开始不是 const

我又想把它变成 const

那么也可以做这样一个转型

所以说用了 const_cast 这个关键字

原来的量有 const 的 结果就变成非 const

原来是非 const 结果就会变成 const 的

就是临时取消或设置一下那个量的 const 状态

做的就是这个事

为什么需要它呢 就是有的时候

我们程序代码的逻辑所决定的

一开始我有一个对象

它是一个常对象

我又想临时处理一下它的那个值

想修改一下

那么我就需要一次 const_cast 一次转型

如果这样一个量一开始不是 const 的量

但是我又需要把它传给一个 const 量

理论上可以直接传

但是某些特殊的场合

还是应该把它先转换成 const 量之后再传

语义上更恰当 就这个意思

特别需要说明的是

如果原始数据对象本身你不能够写入

原来真地是一个 const 量

那么你想把它转换成非 const 量以后

真地把它写入进去

那么取消这个 const

就有可能导致未知的结果

所以说 const_cast

它的最常用的一个场合

就是参数传递的时候

它那个实际参数和形式参数

const 状态的一次变化

我们看一个例子 有一个类 ConstCastTest

在这里边我定义一个 const 函数 PrintNum()

这样的 const 函数本质上

是不允许修改我们目标数据对象的值的

在这里访问的将是 private 这个 _num 这个成员

在这里访问的将是 private 这个 _num 这个成员

它不能修改 它只是打印

但是偶尔我们可能需要修改它

_num 本身是可以修改的

但是 PrintNum() 是不能修改它的

所以在这种情况下

如果你要在 PrintNum() 里边

想修改那个 _num 那个成员的值

那么就必须临时地将 this 指针

转型成 ConstCastTest * 才能访问 _num

原因就是这是一个 const 函数

所以传过来的那个 this 指针

它不是指向 ConstCastTest

而是指向 const ConstCastTest

是指向常对象的指针

而不是指向这个对象的指针

这是最重要的一个地方

在使用 const_cast 的时候

同学们要特别注意的地方

这个时候必须做一次常量转型

否则是没有办法操作的

第四个叫 reinterpret_cast

中间也有“_”

我把它翻译成复诠转型

“interpret”就是“解释”、“阐释”

我们这里面就是“诠释”

“re”就是“再” 再解释的意思

所以我把它翻译成复诠转型

复诠转型的目的是什么呢

它将任意型式的数据对象

转型为目标型式

也就是说 它将重新地解释

你那个数据的位序列的意义

它可以用于任意型式的转型

尤其是指针和整数之间的互转

复诠转型功能虽然非常强大

但是它有一个重要的问题

就是转型是不是成功 是不是合法的

需要由程序员来保证

你必须保证它是有意义的

编译器本身

它只是简单地按照目标型式

重新解释那片存储区的内容

它原来不是另外一个数据型吗 OK

它按照目标型重新解释那片存储区的内容

它按照目标型重新解释那片存储区的内容

它并不管这个解释是对的 还是错的

所以你 程序员必须确保这个解释是对的

所以你 程序员必须确保这个解释是对的

这个复诠转型重要性和它的问题就都体现在这里

这个复诠转型重要性和它的问题就都体现在这里

重要性就是它几乎可以做任何转型

问题就在于这个转型是不是对的

由程序员来决定

你程序写错了那这个转型就是错的

需要特别说明的是

在 64 位操作系统下边

指针可能是 64 位宽的

而我们整数可能是32位宽的

在将一个整数和一个指针进行转型的时候

在将一个整数和一个指针进行转型的时候

复诠转型有可能会丢失数据

或者带来错误的结果

所以使用的时候就需要特别小心

如果是 32 位的系统 32 位的编译器

那么这个转型就一点问题都没有

因为整型和指针型两者的尺寸是一样的

我们看这样一个例子

我定义一个函数 f()

接受一个哑型指针 p 作为它的参数

我在这里会把哑型指针

重新转换成 unsigned int

转换成一个无符号的整数赋值给 n

然后返回 n 没有问题

p 是什么 p 是一个对象的地址

那么我们就把那个对象的地址值

转换成一个整数

然后输出那个整数 完事了

其实不仅仅是输出

你做了这个指针转型之后

你都可以在那个整数上边做运算

比如说加 4、减 4

做这样的运算没有问题

可以去处理的

基于Linux的C++课程列表:

第一讲 C/C++基本语法元素

-1.1 提纲

--LinuxCPP0101

-1.2 程序设计的基本概念

--LinuxCPP0102

-1.3 简单C/C++程序介绍

--LinuxCPP0103

-1.4 程序设计的基本流程

--LinuxCPP0104

-1.5 基本语法元素

--LinuxCPP0105

-1.6 程序设计风格

--LinuxCPP0106

-1.7 编程实践

--LinuxCPP0107

-第一讲 C/C++基本语法元素--编程实践提交入口

第二讲 程序控制结构

-2.1 提纲

--LinuxCPP0201

-2.2 结构化程序设计基础

--LinuxCPP0202

-2.3 布尔数据

--LinuxCPP0203

-2.4 分支结构

--LinuxCPP0204

-2.5 break语句

--LinuxCPP0205

-2.6 循环结构

--LinuxCPP0206

-2.7 编程实践

--LinuxCPP0207

-第二讲 程序控制结构--编程实践提交入口

第三讲 函数

-3.1 提纲

--LinuxCPP0301

-3.2 函数声明、调用与定义

--LinuxCPP0302

-3.3 函数调用栈框架

--LinuxCPP0303

-3.4 编程实践

--LinuxCPP0304

-第三讲 函数--编程实践提交入口

第四讲 算法

-4.1 提纲

--LinuxCPP0401

-4.2 算法概念与特征

--LinuxCPP0402

-4.3 算法描述

--LinuxCPP0403

-4.4 算法设计与实现

--LinuxCPP0404

-4.5 递归算法(一)

--LinuxCPP0405

-4.6 递归算法(二)

--LinuxCPP0406

-4.7 容错与计算复杂度

--LinuxCPP0407

-4.8 编程实践

--LinuxCPP0408

-第四讲 算法--编程实践提交入口

第五讲 程序组织与开发方法

-5.1 提纲

--LinuxCPP0501

-5.2 库与接口

--LinuxCPP0502

-5.3 随机数库(一)

--LinuxCPP0503

-5.4 随机数库(二)

--LinuxCPP0504

-5.5 作用域与生存期

--LinuxCPP0505

-5.6 典型软件开发流程(一)

--LinuxCPP0506

-5.7 典型软件开发流程(二)

--LinuxCPP0507

-5.8 编程实践

--LinuxCPP0508

-第五讲 程序组织与开发方法--编程实践提交入口

第六讲 复合数据类型

-6.1 提纲

--LinuxCPP0601

-6.2 字符

--LinuxCPP0602

-6.3 数组(一)

--LinuxCPP0603

-6.4 数组(二)

--LinuxCPP0604

-6.5 结构体

--LinuxCPP0605

-6.6 编程实践

--LinuxCPP0606

-第六讲 复合数据类型--编程实践提交入口

第七讲 指针与引用

-7.1 提纲

--LinuxCPP0701

-7.2 指针基本概念

--LinuxCPP0702

-7.3 指针与函数

--LinuxCPP0703

-7.4 指针与复合数据类型(一)

--LinuxCPP0704

-7.5 指针与复合数据类型(二)

--LinuxCPP0705

-7.6 字符串

--LinuxCPP0706

-7.7 动态存储管理(一)

--LinuxCPP0707

-7.8 动态存储管理(二)

--LinuxCPP0708

-7.9 引用

--LinuxCPP0709

-7.10 编程实践

--LinuxCPP0710

-第七讲 指针与引用--编程实践提交入口

第八讲 链表与程序抽象

-8.1 提纲

--LinuxCPP0801

-8.2 数据抽象(一)

--LinuxCPP0802

-8.3 数据抽象(二)

--LinuxCPP0803

-8.4 链表(一)

--LinuxCPP0804

-8.5 链表(二)

--LinuxCPP0805

-8.6 链表(三)

--LinuxCPP0806

-8.7 链表(四)

--LinuxCPP0807

-8.8 函数指针(一)

--LinuxCPP0808

-8.9 函数指针(二)

--LinuxCPP0809

-8.10 抽象链表(一)

--LinuxCPP0810

-8.11 抽象链表(二)

--LinuxCPP0811

-8.12 编程实践

--LinuxCPP0812

-第八讲 链表与程序抽象--编程实践提交入口

第九讲 类与对象

-9.1 提纲

--LinuxCPP0901

-9.2 程序抽象与面向对象

--LinuxCPP0902

-9.3 类类型

--LinuxCPP0903

-9.4 对象(一)

--LinuxCPP0904

-9.5 对象(二)

--LinuxCPP0905

-9.6 类与对象的成员(一)

--LinuxCPP0906

-9.7 类与对象的成员(二)

--LinuxCPP0907

-9.8 类与对象的成员(三)

--LinuxCPP0908

-9.9 继承(一)

--LinuxCPP0909

-9.10 继承(二)

--LinuxCPP0910

-9.11 继承(三)

--LinuxCPP0911

-9.12 多态(一)

--LinuxCPP0912

-9.13 多态(二)

--LinuxCPP0913

-9.14 编程实践

--LinuxCPP0914

-第九讲 类与对象--编程实践提交入口

第十讲 操作符重载

-10.1 提纲

--LinuxCPP1001

-10.2 四则运算符重载(一)

--LinuxCPP1002

-10.3 四则运算符重载(二)

--LinuxCPP1003

-10.4 关系与下标操作符重载

--LinuxCPP1004

-10.5 赋值操作符重载(一)

--LinuxCPP1005

-10.6 赋值操作符重载(二)

--LinuxCPP1006

-10.7 赋值操作符重载(三)

--LinuxCPP1007

-10.8 赋值操作符重载(四)

--LinuxCPP1008

-10.9 赋值操作符重载(五)

--LinuxCPP1009

-10.10 流操作符重载(一)

--LinuxCPP1010

-10.11 流操作符重载(二)

--LinuxCPP1011

-10.12 流操作符重载(三)

--LinuxCPP1012

-10.13 操作符重载总结

--LinuxCPP1013

-10.14 编程实践

--LinuxCPP1014

-第十讲 操作符重载--编程实践提交入口

第十一讲 泛型编程

-11.1 提纲

--LinuxCPP1101

-11.2 泛型编程概览

--LinuxCPP1102

-11.3 异常处理机制(一)

--LinuxCPP1103

-11.4 异常处理机制(二)

--LinuxCPP1104

-11.5 运行期型式信息(一)

--LinuxCPP1105

-11.6 运行期型式信息(二)

--LinuxCPP1106

-11.7 模板与型式参数化

--LinuxCPP1107

-11.8 题外话:术语翻译

--LinuxCPP1108

-11.9 泛型编程实践(一)

--LinuxCPP1109

-11.10 泛型编程实践(二)

--LinuxCPP1110

-11.11 泛型编程实践(三)

--LinuxCPP1111

-11.12 泛型编程实践(四)

--LinuxCPP1112

-11.13 泛型编程实践(五)

--LinuxCPP1113

-11.14 泛型编程实践(六)

--LinuxCPP1114

-11.15 泛型编程实践(七)

--LinuxCPP1115

-11.16 泛型编程实践(八)

--LinuxCPP1116

-11.17 泛型编程实践(九)

--LinuxCPP1117

-11.18 泛型编程实践(十)

--LinuxCPP1118

-11.19 编程实践

--LinuxCPP1119

-第十一讲 泛型编程--编程实践提交入口

第十二讲 Linux系统编程基础

-12.1 提纲

--LinuxCPP1201

-12.2 程序执行环境(一)

--LinuxCPP1202

-12.3 程序执行环境(二)

--LinuxCPP1203

-12.4 程序执行环境(三)

--LinuxCPP1204

-12.5 程序执行环境(四)

--LinuxCPP1205

-12.6 输入输出(一)

--LinuxCPP1206

-12.7 输入输出(二)

--LinuxCPP1207

-12.8 文件系统

--LinuxCPP1208

-12.9 设备

--LinuxCPP1209

-12.10 库(一)

--LinuxCPP1210

-12.11 库(二)

--LinuxCPP1211

-12.12 makefile文件(一)

--LinuxCPP1212

-12.13 makefile文件(二)

--LinuxCPP1213

-12.14 makefile文件(三)

--LinuxCPP1214

-12.15 编程实践

--LinuxCPP1215

-第十二讲 Linux系统编程基础--编程实践提交入口

第十三讲 进程编程

-13.01 提纲

--LinuxCPP1301

-13.02 进程基本概念

--LinuxCPP1302

-13.03 信号

--LinuxCPP1303

-13.04 进程管理(一)

--LinuxCPP1304

-13.05 进程管理(二)

--LinuxCPP1305

-13.06 进程管理(三)

--LinuxCPP1306

-13.07 进程间通信(一)

--LinuxCPP1307

-13.08 进程间通信(二)

--LinuxCPP1308

-13.09 进程间通信(三)

--LinuxCPP1309

-13.10 进程间通信(四)

--LinuxCPP1310

-13.11 进程池

--LinuxCPP1311

-13.12 编程实践

--LinuxCPP1312

-第十三讲 进程编程--编程实践提交入口

第十四讲 线程编程

-14.1 提纲

--LinuxCPP1401

-14.2 线程基本概念

--LinuxCPP1402

-14.3 线程管理(一)

--LinuxCPP1403

-14.4 线程管理(二)

--LinuxCPP1404

-14.5 线程管理(三)

--LinuxCPP1405

-14.6 线程管理(四)

--LinuxCPP1406

-14.7 线程同步机制(一)

--LinuxCPP1407

-14.8 线程同步机制(二)

--LinuxCPP1408

-14.9 C++11线程库(一)

--LinuxCPP1409

-14.10 C++11线程库(二)

--LinuxCPP1410

-14.11 C++11线程库(三)

--LinuxCPP1411

-14.12 C++11线程库(四)

--LinuxCPP1412

-14.13 C++11线程库(五)

--LinuxCPP1413

-14.14 编程实践

--LinuxCPP1414

-第十四讲 线程编程--编程实践提交入口

第十五讲 网络编程

-15.1 提纲

--LinuxCPP1501

-15.2 Internet网络协议

--LinuxCPP1502

-15.3 套接字(一)

--LinuxCPP1503

-15.4 套接字(二)

--LinuxCPP1504

-15.5 编程实践

--LinuxCPP1505

-第十五讲 网络编程--编程实践提交入口

课程文档

-课程PDF文件

LinuxCPP1106笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。