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的更多相关文章

  1. 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 ...

  2. SSH整合时执行hibernate查询报错:java.lang.ClassCastException: com.ch.hibernate.Department_$$_javassist_0 cannot be cast to javassist.util.proxy

    今天在整合ssh三个框架时,有一个功能,是查询所有员工信息,且员工表和部门表是多对一的映射关系,代码能正常运行到查询得到一个List集合,但在页面展示的时候,就报异常了, java.lang.Clas ...

  3. 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 ...

  4. Java Class.cast方法

    1.Java api public T cast(Object obj); Casts an object to the class or interface represented 解释的比较笼统, ...

  5. SELECT CAST(GETDATE() AS VARCHAR(10)) 显示不同格式的原因

    开发人员测试时,发现生产服务器与测试服务器执行SELECT CAST(GETDATE() AS VARCHAR(10))语句显示的格式不一样.如下所示 Server A Server B 其实出现这个 ...

  6. 【MySQL】使用Length和Cast函数计算TEXT类型字段的长度

    背景: 前段时间,业务需要,为了快速让解析的Excel入库,所以把不是很确定的字段全部设置成了TEXT. 今天需要进行表结构优化,把字段长度控制在合适的范围,并尽量不使用TEXT类型. -- 计算长度 ...

  7. sql 中convert和cast区别

    SQL中的cast和convert的用法和区别 更多 来源:SQL学习浏览量: 学习标签: cast convert sql 本文导读:SQL中的cast 和convert都是用来将一种数据类型的表达 ...

  8. postgres 类型转换 cast 转

    转自: http://blog.csdn.net/yufenghyc/article/details/45869509 --1 例子postgres=# select 1/4; ?column? -- ...

  9. 错误 java.lang.ClassCastException: com.ylpw.sms.YZZYSenderUtil cannot be cast to ResourceBundle

    出现错误: java.lang.ClassCastException: com.ylpw.sms.YZZYSenderUtil cannot be cast to ResourceBundle 百度搜 ...

随机推荐

  1. iOS 下拉刷新-上拉加载原理

    前言 讲下拉刷新及上拉加载之前先给大家解释UIScrollView的几个属性 contentSize是UIScrollView可以滚动的区域. contentOfinset 苹果官方文档的解释是&qu ...

  2. IT软件技术人员的职位路线(从程序员到技术总监) - 部门管理经验谈

    以前写过一个文(IT从业者的职业道路(从程序员到部门经理) - 项目管理系列文章),主要介绍笔者的职业发展之路,不过该文需要后续了,因为笔者现在从事的是“产品经理”一职.从笔者的导航文([置顶]博文快 ...

  3. [Erlang 0110] Erlang Abstract Format , Part 1

    Erlang Abstract Format并不难懂,只是枯燥一点罢了,如果把Abstract Format的文档翻译出来,其实就是Erlang教科书中语法入门的部分. Erlang Abstract ...

  4. Solr实战:使用Hue+Solr实现标签查询

    公司最近在研究多条件组合查询方案,Google的一位技术专家Sam和我们讨论了几个备选方案. Sam的信: 我做了进一步研究,目前有这么几种做法: 1) 最直接粗暴,只做一个主index,比如按行业+ ...

  5. 15天玩转redis —— 第九篇 发布/订阅模式

    本系列已经过半了,这一篇我们来看看redis好玩的发布订阅模式,其实在很多的MQ产品中都存在这样的一个模式,我们常听到的一个例子 就是邮件订阅的场景,什么意思呢,也就是说100个人订阅了你的博客,如果 ...

  6. 【转】XenServer架构之XAPI的调用流程

    XAPI 调用是使用XML-RPC协议通过网络发送到安装有XenServer 的主机上.XAPI对象的引用不保证对象的永久标识符,引用不允许对象进行相等比较.对同一物体的两个引用,不保证是文本相同的. ...

  7. Ubuntu 14.04 LTS 下升级 gcc 到 gcc-4.9、gcc-5 版本

    如果没记错的话,阿里云ECS上的Ubuntu也是LTS版本. 如果还在使用较旧版本的Ubuntu,或者是Ubuntu LTS,那么我们是很难体验新版gcc的.怎么办呢? 我们或许可以自己去编译用旧版本 ...

  8. [LeetCode] Word Pattern II 词语模式之二

    Given a pattern and a string str, find if str follows the same pattern. Here follow means a full mat ...

  9. [LeetCode] Trapping Rain Water 收集雨水

    Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...

  10. Redis系列之(二):Redis主从同步,读写分离

    1. Redis主从同步 Redis支持主从同步.数据可以从主服务器向任意数量的从服务器上同步,同步使用的是发布/订阅机制. 2. 配置主从同步 Mater Slave的模式,从Slave向Maste ...