C++进阶--显式类型转换(casting)
//############################################################################
/*
* 显式类型转换
*
* 类型转换
* 1. 隐式
* 2. 显式 - Casting
*/
/*
* 1. static_cast
*/
int i = 9;
float f = static_cast<float>(i); // 将对象从一个类型转为另一个类型
dog d1 = static_cast<dog>(string("Bob")); // 需要定义类型转换函数
dog* pd = static_cast<dog*>(new yellowdog()); // 将指针/引用从一个类型转为一个相关的类型(down/up cast)
/*
* 2. dynamic_cast
*/
dog* pd = new yellowdog();
yellowdog py = dynamic_cast<yellowdog*>(pd);
// a. 将指针/引用从一个类型转为一个相关的类型(down cast) 只能用于指针和引用,基本上用于基类转成派生类
// b. 运行时类型检查。如果成功, py==pd; 如果失败, py==0;
// c. 要求2个类型是多态的 (有虚函数).
/*
* 3. const_cast
*/ // 只能用于指针和引用
const char* str = "Hello, world."; // 只能用于同一类型
char* modifiable = const_cast<char*>(str); // 去除所指的对象的const属性
/*
* 4. reinterpret_cast
*/
long p = 51110980;
dog* dd = reinterpret_cast<dog*>(p); // 重新解释所指对象的比特位
// 可以将指针转成任意其他类型的指针
/*
* C-Style Casting:
*/
short a = 2000;
int i = (int)a; // c-like cast表示法
int j = int(a); // 类函数表示法
// 是static_cast, const_cast and reinterpret_cast的混合
/*
* 更倾向于C++风格的转换,因为:
* 1. 更具倾向性,代码易于阅读
* 2. 更少的使用错误. C++风格提供:
* a. 每种转换具有更窄的目的
* b. 运行时检查能力
*/
/*
* 转换有风险
*
* dynamic_cast的例子:
*/
class dog {
public:
virtual ~dog() {}
};
class yellowdog : public dog {
int age;
public:
void bark() { cout<< "woof. I am " << age << endl; } //bark没有访问任何成员数据,编译器会试图将其解释为静态函数处理
};
int main() {
dog* pd = new dog();
yellowdog* py = dynamic_cast<yellowdog*>(pd); //运行时类型检查开销很大
py->bark(); //所以这里可以成功
cout << "py = " << py << endl;
cout << "pd = " << pd << endl;
...
}
OUTPUT:
woof.
py = 0
pd = 57873400
/* 转换可以是一个方便的黑客工具 */
class dog {
public:
std::string m_name;
dog():m_name("Bob") {}
void bark() const { //*this is const
std::cout << "My name is " << m_name << std::endl;
}
};
// m_name = "Henry";
// const_cast<dog*>(this)->m_name = "Henry";
/* 【各类转换的比较】
* Generate_Code 转换是否会产生相当数据的可执行代码
* Generate_date 转换是否会产生不同的数据类型
* risky 风险等级
* data_type 可用于哪些类型
* ========================================= C++ 风格转换 ================================
* Generate_Code Generate_data risky data_type
* Object Casting:
* static_cast yes yes 2 any types
* (as long as type
* conversion is defined)
* Pointer/Reference Casting:
* static_cast no no 4 related types
* dynamic_cast yes no 3 related types(down-cast)
* const_cast no no 1 same type
* reinterpret_cast no no 5 any types
*
*
*
*
* ========================================= C 风格转换 ================================
* Generate_Code Generate_data risky data_type
* Object Casting: yes yes 5 any types
* (as long as type
* conversion is defined)
* Pointer/Reference Casting: no no 5 any types
*
*
*
*
* 注意:
* 1. const_cast, dynamic_cast和reinterpret_cast只能用于指针/引用
* 2. 对象的static_cast和指针的static_cast差别非常大
* 3. reinterpret_cast从比特上重新分配类型信息,用在低层的编码上
* 4. dynamic_cast相比static_cast加上了运行时类型检查
* 5. dynamic_cast和static_cast指针转换时只能转成有关的类型 (即, 基类 <-> 派生类之间转换).
*
*/
/* 使用多态最小化转换的使用
如下例子的转换,可以用多态实现
*/
class dog {
public:
virtual ~dog() {}
};
class yellowdog : public dog {
public:
void bark() { cout<< "Yellow dog rules! " << endl; }
};
int main() {
dog* pd = get_dog();
if (yellowdog *py = dynamic_cast<yellowdog*>(pd)) {
py->bark();
}
delete pd;
}
/* 增加虚函数bark()*/
class dog {
public:
virtual ~dog() {}
virtual void bark() {}
};
class yellowdog : public dog {
public:
void bark() { cout<< "Yellow dog rules! " << endl; }
};
int main() {
dog* pd = get_dog();
pd->bark();
delete pd;
}
C++进阶--显式类型转换(casting)的更多相关文章
- C#中,使用显式类型转换(int)和Math.Round方法,将浮点数转换为整数的区别
主要区别就是,显式类型转换(int)是将浮点数的整数部分截取出来,然后转换为整数,所以相当于是向下取整.而Math.Round方法是对浮点数进行四舍五入后,转换为整数. 新建一个.NET Core控制 ...
- C++显式类型转换
C++显式类型转换 (注:本文例程改编自<C++ Primer>) 关于类型转换,C++保留了C语言中的类型转换方式,并提供了4中新的类型转换方式.<Effective C++> ...
- SQL进阶-隐式类型转换
一.隐式类型转换 1.隐式类型转换 隐式类型转换: '; 程序可读性差,且依赖数据库的隐式转换规则,如果数据库升级,则程序可能无法正确执行: 有可能会导致索引失效: 有可能会导致意想不到的结果: 显式 ...
- C++进阶--隐式类型转换
//############################################################################ /* 隐式类型转换 * * 类型转换可分为 ...
- javascript显式类型转换
尽管js可以做许多自动类型转换,但某些时候仍然需要做显示类型转换或为了代码逻辑清晰易读而做显示类型转换. 做显示类型转换最简单的方法就是用Boolean().Number().String()或Obj ...
- JavaScript显式类型转换与隐式类型转换
隐式类型转换 四则运算 判断语句 toString 在 JavaScript 中声明变量不需指定类型,对变量赋值也没有类型检查,同时还允许隐式类型转换. 这些特征说明 JavaScript 属于弱类型 ...
- C++中的显式类型转换
一.学习总结 1.C++中额外提供的类型转换有 (1) reinterpret_cast: 格式:reinterpret_cast<type-id> (expression)①type-i ...
- C++学习之显式类型转换与运行时类型识别RTTI
static_cast const_cast reinterpret_cast 运行时类型识别(RTTI) dynamic_cast 哪种情况下dynamic_cast和static_cast使用的情 ...
- Golang 类型转换,断言和显式强制转换
1 前言 类型转换,可以用断言(只能使用在interface{}类型转换成其它类型)和显式类型强制转换(常规是用于基本类型) 2 代码 //graphql-go func(params graphql ...
随机推荐
- 解决cocos2dx调用removeFromParent后报错问题
原因:cocos2dx的bug 解决办法: 放到action中,前面添加一个DelayTime延迟,代码如下 this->runAction(Sequence::create(DelayTime ...
- ZOJ - 4082:Little Sub and his Geometry Problem (双指针)
Little Sub loves math very much, and has just come up with an interesting problem when he is working ...
- HDU1272小希的迷宫–并查集
上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走.但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了 ...
- Java线程池 详解(图解)
来源:www.jianshu.com/p/098819be088c 拓展: 手动创建 new ThreadPoolExecutor 的使用: https://segmentfault.com/a/11 ...
- Linux 命令:文件目录操作与实例
来源: http://blog.51cto.com/yuanzhitang/2056994 本文介绍基础的文件操作:创建,移动,编辑,删除 文件和文件夹 命令与案例: mkdir 创建目录 - ...
- Java基础四(switch、数组、)
1.流程控制语句switch2.数组3.随机点名器案例 ###01switch语句解构 * A:switch语句解构 * a:switch只能针对某个表达式的值作出判断,从而决定程序执行哪一段代码. ...
- goland 文件头注释
打开GoLand的setting选项 依次选择Editor,CodeStyle ,File and Code Templates ,Go File 根据自己需要添加即可 /* @Time : ${DA ...
- linux网络编程概念(一)
AF表示地址族(address family) PF表示协议族(protocol family) domain参数 AF_UNIX 内核中通信 sockaddr_un AF_INET 通过ipv4 s ...
- redis服务以及phpredis扩展的安装
一.下载软件包 下载redis wget http://download.redis.io/releases/redis-3.0.7.tar.gz 下载redis的php扩展 wget http:// ...
- 07机器学习实战k-means
K-Means原理初探 K-Means算法的思想很简单,对于给定的样本集,按照样本之间的距离大小,将样本集划分为K个簇.让簇内的点尽量紧密的连在一起,而让簇间的距离尽量的大. 如果我们想直接求上式的最 ...