1首先来回顾C的强制转换

大家都知道,在编译C语言中的强制转换时,编译器不会检查转换是否成功,都会编译正确.

比如:

#include "stdio.h"

struct Position
{
int x;
int y;
}; int main()
{
int i;
struct Position *p; i=0x123456; p=(struct Position *)i; printf("px=%d,py=%d\n",p->x,p->y);
}

输出结果如下图所示:

从上图可以看到,只有当运行代码时,才会出现段错误问题.

当C代码上千行时,若出现这种问题,是非常难找的.

2.C++的新型类型转换

所以在C++中,便引入了4强制类型转换

2.1 static_cast(静态类型转换)

  • 用于基本数据类型以及对象之间的转换(char,int,const int等)
  • 不能用于基本数据类型指针之间的转换(char *,int *等)
  • 用于有继承关系类对象指针之间的转换
  • 用于类指针之间的转换

示例-基本数据:

    int i = 0x45;

    char c = 'c';

    c = static_cast<char>(i);
//char* pc = static_cast<char*>(&i); //此行错误,不能用于基本指针之间转换

示例-基本数据与对象转换:

class Test{

public:
explicit Test(int i) //只能显示调用
{
cout<<i<<endl;
}
};
int main()
{
Test t = static_cast<Test>(3.55); //等价于 : Test t(3);
}

示例-有继承关系的类对象指针转换:

class Parent
{
public:
int mm;
Parent(int i)
{
mm=i;
cout<<"Parent:"<<i<<endl;
} }; class Child : public Parent
{
public:
int mval;
Child(int i):Parent(i)
{
mval=i;
cout<<"Child:"<<i<<endl;
}
}; int main()
{
Parent *p =new Parent(); //会调用父类构造函数
Child *c = static_cast <Child *> (p) ; //并不会调用子类构造函数,此时的mval成员为随机值
c->mval=;
cout<<"mval:"<<c->mval<<endl;

    cout<<"mm:"<<c->mm<<endl;          //此时的c->mm指向的对象就是p->mm
    c->mm=100;                   //修改c->mm 等价于修改p->mm
    cout<<"mm:"<<p->mm<<endl;

}                   

运行打印:

Parent:
mval:100
mm:3
mm:100

2.2 const_cast(去常类型转换)

  • 常用于去除const类对象只读属性
  • 且强制转换的类型必须是指针*引用&

示例1:

const int x =;     //const:定义一个常量x 

const int& j =;    //const引用:定义一个只读变量j

int& p1= const_cast<int&>(x);   //强制转换int &

int *p2 = const_cast<int*>(&j);  //强制转换int*

//int p3 = const_cast<int>(j);    //此行错误,不能转换普通数据型

p1=;
*p2=; printf("x=%d, j=%d\n",x,j);
printf("p1=%d *p2=%d\n",p1,*p2);

输出结果:

x=   j=

p1=  *p2=

从输出结果,可以看出修改p1,p2,只有j内容变换了,是因为变量j用const引用定义的,所以是个只读变量.

示例2-去除const类对象的只读属性

class Test
{
public:
int mval;
Test():mval()
{ }
}; int main()
{
const Test n1; //n1.mval = 100; //error,不能直接修改常量对象的成员 Test *n2 = const_cast<Test *>(&n1); //通过指针*转换
Test &n3 = const_cast<Test &>(n1); //通过引用&转换 n2->mval = ; cout<<n1.mval<<endl;        //打印20 n3.mval = ; cout<<n1.mval<<endl;        //打印30
}

2.3 dynamic_cast(动态类型转换)

  • 用于有继承关系的类指针(引用)间的转换
  • 用于有交叉关系的类指针(引用)间的转换
  • 具有类型检查的功能,编译时会去检查使用的方法是否正确,转换是否成功只有在程序运行时才能知道
  • 类中必须有虚函数的支持
  • 不能用于基本数据类型指针之间的转换(char *,int *等)

-当转换为指针时:

  •  转换成功  : 得到目标类型的指针
  • 转换失败  : 得到一个空指针

-当转换为引用时:

  •  转换成功  : 得到目标类型的引用
  • 转换失败  : 得到一个异常操作信息

示例-通过子类指针去指向父类:

#include <iostream>

using namespace std;

class Base
{
public:
Base()
{
cout << "Base::Base()" << endl;
} virtual ~Base()
{
cout << "Base::~Base()" << endl;
}
}; class Derived : public Base
{
}; int main()
{
Base* p = new Base; //初始化父类指针 Derived* pd = dynamic_cast<Derived*>(p); //由于父类指针指向的是父类,没有子类虚函数表,所以转换失败
cout << "pd = " << pd << endl; //转换失败,打印 0 delete p; p = new Derived;
pd = dynamic_cast<Derived*>(p); //由于父类指针指向的是子类,所以有子类虚函数表
cout <<"pd = " << pd <<endl; //转换成功,打印地址值 delete p; return ;
}

 示例-通过多重继承下的类指针转换: 

class BaseA
{
public:
virtual void funcA()
{
cout<<"BaseA: funcA()"<<endl;
} };
class BaseB
{
public:
virtual void funcB()
{
cout<<"BaseB: funcB()"<<endl;
} };
class Derived : public BaseA,public BaseB
{
};
int main()
{
Derived d;
BaseA *pa=&d; pa->funcA(); //打印 BaseA: funcA() /*通过强制转换执行*/
BaseB *pb=(BaseB *)pa;
pb->funcB(); //还是打印 BaseA: funcA(), 因为pb还是指向pa,执行的还是pa的虚函数表 /*通过dynamic_cast执行*/
pb = dynamic_cast<BaseB *>(pa);
pb->funcB(); //打印 BaseB: funcB()
//编译器会去检测pa所在的地址,发现有多个虚函数表,然后根据 <BaseB *>来修正指针pb
return ; }

2.4 reinterpret_ cast(解读类型转换)

  • 用于所有指针的强制转换

(解读是指:对要转换的数据进行重新的解读)

例如:

    int i = ;

    char j='c';
int *p1=reinterpret_cast<int *>(&i); char *p2=reinterpret_cast<char *>(&j); //int p3=reinterpret_cast<int >i; //此行错误,不能转换普通数据型

5.C++里的4种新型类型转换的更多相关文章

  1. C++中四种强制类型转换区别详解

    C++即支持C风格的类型转换,又有自己风格的类型转换.C风格的转换格式很简单,但是有不少缺点的: 1.转换太过随意,可以在任意类型之间转换.你可以把一个指向const对象的指针转换成指向非const对 ...

  2. [转载]C++中四种强制类型转换方式

    C++中四种强制类型转换方式 原文地址:http://www.cnblogs.com/home123/p/6763967.html 类型转换有c风格的,当然还有c++风格的.c风格的转换的格式很简单( ...

  3. MVVM 一种新型架构框架

    MVVM是Model-View-ViewModel的简写.微软的WPF带来了新的技术体验,如Silverlight.音频.视频.3D.动画……,这导致了软件UI层更加细节化.可定制化.同时,在技术层面 ...

  4. Android TextView里显示两种颜色

    今天介绍一个小技巧,在Android的TextView里设置两种颜色,直接上代码: TextView TV = (TextView)findViewById(R.id.mytextview01); S ...

  5. C#中,三种强制类型转换的对比

    在C#中,我们可以看到三种强制类型转换,比如强制转换成有符号32位整型,可以找到下面三种方式: ① (int)()                ②Convert.ToInt32()          ...

  6. Galera Cluster——一种新型的高一致性MySQL集群架构

    原文链接:https://www.sohu.com/a/147032902_505779,最近被分配定位mysql的问题,学习下. 1. 何谓Galera Cluster 何谓Galera Clust ...

  7. 一种新型远距临场机器人 Fusion / Full Body Surrogacy for Collaborative Communication

    近日,来自日本庆应大学的机器人专家开发出一种新型远距临场机器人 Fusion,允许操作者远程控制别人的身体来帮助他们完成操作任务.Fusion「栖居」在代理者的背上,具备立体视觉和双声道听觉,可以通过 ...

  8. 四种强制类型转换的总结(const_cast、static_cast、dynamic_cast、reinterpreter_cast)

    四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast) 转载 2011年10月03日 23:59:05 标签: stru ...

  9. C++中的关键字用法--- 四种强制类型转换的总结

    四种强制类型转换的总结(const_cast.static_cast.dynamic_cast.reinterpreter_cast 1. C风格的强制类型转换(Type Cast)很简单,不管什么类 ...

随机推荐

  1. 人生苦短,我用Python 第一篇

    一.变量名 自定义变量名只能用 数字.字母.下划线组成. 使用变量前,需对其先赋值 注意:1.变量名不能以数字开头:      2.不能是关键字:例如:'and', 'as', 'assert', ' ...

  2. POJ 3041 Asteroids(模板——二分最大匹配(BFS增广))

    题目链接: http://poj.org/problem?id=3041 Description Bessie wants to navigate her spaceship through a da ...

  3. 一步一步创建ASP.NET MVC5程序[Repository+Autofac+Automapper+SqlSugar](六)

    前言 大家好,我是Rector 又是星期五,很兴奋,很高兴,很high...啦啦啦... Rector在图享网又和大家见面啦!!!上一篇<一步一步创建ASP.NET MVC5程序[Reposit ...

  4. 织梦中data文件夹是存放什么内容的

    dede(织梦)的data文件夹下的文件及文件夹也不少,我们来一个一个的介绍下. 1. admin文件夹 admin文件夹 管理员用到的文件夹,一般是后台的配置文件. 第一个文件,idc.txt 配置 ...

  5. requests关于Exceeded 30 redirects问题得出的结论

    昨天一个朋友在爬网页时出现的一个问题,以及后续我对这个问题进行了简单的测试. 先说出现的问题的简单描述. 首先是使用urllib请求网页: #urllib.request发起的请求 import ur ...

  6. MySQL 水平拆分(读书笔记整理)

    转:http://blog.csdn.net/mchdba/article/details/46278687 1,水平拆分的介绍 一般来说,简单的水平切分主要是将某个访问极其平凡的表再按照某个字段的某 ...

  7. CentOS6.x机器安装Azure CLI2.0【1】

    安装Azure CLI 2.0的前提是:机器中必须有 Python 2.7.x 或 Python 3.x.如果机器中没有其中任何一个Python版本,请及时安装 1.准备一台CentOS 6.9的机器 ...

  8. flask_route错误:AttributeError: 'function' object has no attribute 'route'

    问题: 路由完全正确,当只有一个名为home的函数处理这个路由时候,下一个路由处理函数,总是提示没有这个rotue属性 Traceback (most recent call last): File ...

  9. 爬取知名社区技术文章_items_2

    item中定义获取的字段和原始数据进行处理并合法化数据 #!/usr/bin/python3 # -*- coding: utf-8 -*- import scrapy import hashlib ...

  10. BSA Network Shell系列-runcmd/runscript命令

    runcmd和runscript ## 1 功能概述 runcmd/runscript:runcmd在一台或多台机器执行Network Shell命令(单个命令),而runscript执行的是脚本,二 ...