C++ cast
excerpted from Type conversions
K&R Section 2.7 p59 对type conversion 的解释:
The precise meaning of a cast is as if the expression were assigned to a variable of the specified type, which is then used in place of the whole construction.
(类型名) 表达式
将被转换的表达式赋值给指定类型的变量,然后用该变量替代上述语句
PART I Implicit conversion 隐式转换
1. fundamental data types 基本类型 (numeric, bool, some pointer)
精度损失: double -> int
2. non-fundamental types 非基本类型
1. NULL指针可以转换为任意类型
2. 任何类型指针可以转换为void *
3. 指针向上转换: 指针派生类的指针可以转换为其基类的指针
(注: pointers to a derived class can be converted to a pointer of an accessible and unambiguous base class, without modifying its const or volatile qualification.)
3. 类的的隐式转换
1.单参数构造函数
2.赋值运算符
3.类型转换运算符
PART II 显示转换
1. explicit 关键字, 防止不必要的隐式转换
explicit 构造函数(...) /* 在构造函数之前加explicit */
2. type casting
("coerced") 强制
convert any pointer into any other pointer type 任意类型转换为其它任意类型
1. functional notaion: y = int (x);
2. c-like notaion: y = (int)x;
3. casting operators 运算符 用来控制类的转换 (多涉及指针和类)
4种运算符 动态,静态,
1.dynamic_cast
两种转换:
upcast (converting from pointer-to-derived to pointer-to-base)
downcast (convert from pointer-to-base to pointer-to-derived)
dynamic_cast can only be used with pointers and references to classes (or with void*). Its purpose is to ensure that the result of the type conversion points to a valid complete object of the destination pointer type.
只能用于指针和引用 或 void *,确保转换结果指向目标类型的完整的合法的对象 (type-safety checks 类型安全检查)
//示例代码
// dynamic_cast
#include <iostream>
#include <exception>
using namespace std; class Base { virtual void dummy() {} };
class Derived: public Base { int a; }; int main () {
try {
Base * pba = new Derived;
Base * pbb = new Base;
Derived * pd; pd = dynamic_cast<Derived*>(pba); // 转换成功, 因为pba指向完整的Deived对象
if (pd==) cout << "Null pointer on first type-cast.\n"; pd = dynamic_cast<Derived*>(pbb); // 转换失败,返回NULL pbb指向基类对象 如果是转换引用(reference)类型失败,则抛出异常bad_cast
if (pd==) cout << "Null pointer on second type-cast.\n"; } catch (exception& e) {cout << "Exception: " << e.what();}
return ;
}
requires Run-Time Type Information (RTTI) to keep track of dynamic types
2.static_cast 类似于dynamic_cast, 可以upcast和downcast,但不做type-safety checks(交由程序员决定,因此省去了检查的开销(overhead))
class Base {};
class Derived: public Base {};
Base * a = new Base;
Derived * b = static_cast<Derived*>(a); // 合法的代码, 但可能在解引用指针时导致runtime errors
void *转换为任意类型
整形值,浮点值,枚举类型转为枚举类型
3.reinterpret_cast 从任意类型到任意类型,即使类型毫不相关,既不检查指针指向的对象,也不检查指针的类型.
converts any pointer type to any other pointer type
The operation result is a simple binary copy of the value from one pointer to the other.操作结果就是简单的对指针按位复制
class A { /* ... */ };
class B { /* ... */ };
A * a = new A;
B * b = reinterpret_cast<B*>(a); // 代码合法, 但don't make sense. 解引用b将是不安全的.
4.const_cast
对指针的const的操作,加上const或者去除cosnt
作用:将一个const指针传给非const的形参
// const_cast
#include <iostream>
using namespace std; void print (char * str) // 如果传入一个const指针, 不经转换的话会报错
{
cout << str << '\n';
} int main () {
const char * c = "sample text";
print ( const_cast<char *> (c) ); // 相当于传入了移除const的临时变量作为参数, 但如果函数写指针指向的对象将导致未定义的行为
return ;
}
PART III
typeid运算符, 检查表达式的类型
typeid (expression)
返回值:typeinfo类型的常量, typeinfo定义在<typeinfo>头文件中
通过==和!=比较typeinfo类型的变量
通过成员函数name()返回描述数据类型名或类名的字符串
// typeid
#include <iostream>
#include <typeinfo>
using namespace std; int main () {
int * a,b;
a=; b=;
if (typeid(a) != typeid(b)) //可以通过==和!=比较typeinfo类型的变量
{
cout << "a and b are of different types:\n";
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
}
return ;
}
a and b are of different types:
a is: int *
b is: int
When typeid is applied to an expression whose type is a polymorphic class, the result is the type of the most derived complete object
当typeid用于多态类型时,结果是最接近派生的类的类型
// typeid, polymorphic class
#include <iostream>
#include <typeinfo>
#include <exception>
using namespace std; class Base { virtual void f(){} };
class Derived : public Base {}; int main () {
try {
Base* a = new Base;
Base* b = new Derived;
cout << "a is: " << typeid(a).name() << '\n';
cout << "b is: " << typeid(b).name() << '\n';
cout << "*a is: " << typeid(*a).name() << '\n';
cout << "*b is: " << typeid(*b).name() << '\n';
} catch (exception& e) { cout << "Exception: " << e.what() << '\n'; }
return ;
}
a is: class Base *
b is: class Base *
*a is: class Base
*b is: class Derived
C++ cast的更多相关文章
- Java-Spring:java.lang.ClassCastException: com.sun.proxy.$Proxy* cannot be cast to***问题解决方案
java.lang.ClassCastException: com.sun.proxy.$Proxy* cannot be cast to***问题解决方案 临床表现: 病例: 定义代理类: @Tra ...
- SSH整合时执行hibernate查询报错:java.lang.ClassCastException: com.ch.hibernate.Department_$$_javassist_0 cannot be cast to javassist.util.proxy
今天在整合ssh三个框架时,有一个功能,是查询所有员工信息,且员工表和部门表是多对一的映射关系,代码能正常运行到查询得到一个List集合,但在页面展示的时候,就报异常了, java.lang.Clas ...
- CAST function should support INT synonym for SIGNED. i.e. CAST(y AS INT)
Login / Register Developer Zone Bugs Home Report a bug Statistics Advanced search Saved searches T ...
- Java Class.cast方法
1.Java api public T cast(Object obj); Casts an object to the class or interface represented 解释的比较笼统, ...
- SELECT CAST(GETDATE() AS VARCHAR(10)) 显示不同格式的原因
开发人员测试时,发现生产服务器与测试服务器执行SELECT CAST(GETDATE() AS VARCHAR(10))语句显示的格式不一样.如下所示 Server A Server B 其实出现这个 ...
- 【MySQL】使用Length和Cast函数计算TEXT类型字段的长度
背景: 前段时间,业务需要,为了快速让解析的Excel入库,所以把不是很确定的字段全部设置成了TEXT. 今天需要进行表结构优化,把字段长度控制在合适的范围,并尽量不使用TEXT类型. -- 计算长度 ...
- sql 中convert和cast区别
SQL中的cast和convert的用法和区别 更多 来源:SQL学习浏览量: 学习标签: cast convert sql 本文导读:SQL中的cast 和convert都是用来将一种数据类型的表达 ...
- postgres 类型转换 cast 转
转自: http://blog.csdn.net/yufenghyc/article/details/45869509 --1 例子postgres=# select 1/4; ?column? -- ...
- 错误 java.lang.ClassCastException: com.ylpw.sms.YZZYSenderUtil cannot be cast to ResourceBundle
出现错误: java.lang.ClassCastException: com.ylpw.sms.YZZYSenderUtil cannot be cast to ResourceBundle 百度搜 ...
随机推荐
- SQL优化技术分析-1:操作符优化
1.IN 操作符 用IN写出来的SQL的优点是比较容易写及清晰易懂,这比较适合现代软件开发的风格.但是用IN的SQL 性能总是比较低的,从Oracle执行的步骤来分析用IN的SQL与不用IN的SQL有 ...
- SQL Sever 博客文章目录(2016-07-06更新)
SQL Server方面的博客文章也陆陆续续的写了不少了,顺便也将这些知识点整理.归纳一下下.方便自己和他人查看. MS SQL 数据类型 三大数据库对比研究系列--数据类型 MS SQL 表和视图 ...
- javaweb项目jsp跳转servlet Error instantiating servlet class 问题
问题: HTTP Status 500 - Error instantiating servlet class RecommenderServlet type Exception report mes ...
- SSDB图形界面管理工具:phpssdbadmin安装部署
环境: 14.04.1-Ubuntu 1.安装Nginx apt-get install nginx ubantu安装完Nginx后,文件结构大致为: 所有的配置文件都在 /etc/nginx下: 启 ...
- Windows下Java环境配置,tomcat安装
问题描述:在Windows下面做Java web相关的项目的时候,Java和tomcat是基础,这里记载一下Java环境的配置以及tomcat的安装和配置. 使用工具:Windows.jdk安装包.t ...
- Excel公式 提取文件路径后缀
我们在代码中获取一个文件路径的后缀,是一个很简单的事. 如C#中,可以通过new FileInfo(filePath).Extension,或者Path.GetExtension(filePath)获 ...
- 如何通过JS调用某段SQL语句
如何通过JS调用某段SQL语句,这样的需求在报表.数据平台开发中很常见.以报表平台FineReport开发为例,例如在点击某个按钮之后,来判断一下数据库条数,再决定下一步操作.那这在后台如何实现呢? ...
- 【转】虚拟机VMware与主机共享文件介绍
from: http://www.cnblogs.com/kerrycode/p/3818095.html 写的比较详细,但是vm版本较旧. 2:通过共享文件夹功能 虚拟机VMware提供了在宿主机与 ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- python-进程&线程
进程(process):相当于一个程序要运行时所需的所有资源的集合,相当于一个车间,不工作 两个进程之间的数据不共享,完全不独立,互相不能访问. 线程(thread):一道单一指令的控制流,寄生在进程 ...