C++简明讲解类型转换的使用与作用

目录
  • 一、C语言中的强制类型转换
  • 二、C语言强制类型转换存在的问题
  • 三、C++ 中的类型转换
  • 四、小结

一、C语言中的强制类型转换

转换的语法如下:

(Type) (Expression)

Type(Expression)

下面看一段C语言中粗暴的类型转换的代码:

#include <stdio.h>
typedef void(PF)(int);
struct Point
{
    int x;
    int y;
};
int main()
{
    int v = 0x12345;
    PF* pf = (PF*)v;
    char c = char(v);
    Point* p = (Point*)v;
    pf(5);
    printf("p->x = %d\n", p->x);
    printf("p->y = %d\n", p->y);
    return 0;
}

在C++的环境下编译后就会发现:

二、C语言强制类型转换存在的问题

过于粗暴

  • 任意类型之间都可以进行转换,编译器很难判断其正确性

难于定位

  • 在源码中无法快速定位所有使用强制类型转换的语句

三、C++ 中的类型转换

C++ 将强制类型转换分为4种不同的类型:

C++强制类型转换

static_cast const_cast
dynamic_cast reinterpret_cast

用法:xxx_cast<Type >( Expression )

static_cast 强制类型转换

  • 用于基本类型间的转换
  • 不能用于基本类型指针间的转换
  • 用于有继承关系类对象之间的转换和类指针之间的转换

const_cast 强制类型转换

  • 用于去除变量的只读属性
  • 强制转换的目标类型必须是指针或引用

reinterpret_cast 强制类型转换

  • 用于指针类型间的强制转换
  • 用于整数和指针类型间的强制转换

dynamic_cast 强制类型转换

  • 用于有继承关系的类指针间的转换
  • 用于有交叉关系的类指针间的转换
  • 具有类型检查的功能
  • 需要虚函数的支持

​​​​​​下面看一段C++类型转换代码:

#include <stdio.h>
void static_cast_demo()
{
    int i = 0x12345;
    char c = 'c';
    int* pi = &i;
    char* pc = &c;
    c = static_cast<char>(i);
    //pc = static_cast<char*>(pi);
}
void const_cast_demo()
{
    const int& j = 1;
    int& k = const_cast<int&>(j);
    const int x = 2;
    int& y = const_cast<int&>(x);
    //int z = const_cast<int>(x);
    k = 5;
    printf("k = %d\n", k);
    printf("j = %d\n", j);
    y = 8;
    printf("x = %d\n", x);
    printf("y = %d\n", y);
    printf("&x = %p\n", &x);
    printf("&y = %p\n", &y);
}
void reinterpret_cast_demo()
{
    int i = 0;
    char c = 'c';
    int* pi = &i;
    char* pc = &c;
    pc = reinterpret_cast<char*>(pi);
    pi = reinterpret_cast<int*>(pc);
    pi = reinterpret_cast<int*>(i);
    //c = reinterpret_cast<char>(i);
}
void dynamic_cast_demo()
{
    int i = 0;
    int* pi = &i;
    //char* pc = dynamic_cast<char*>(pi);
}
int main()
{
    static_cast_demo();
    const_cast_demo();
    reinterpret_cast_demo();
    dynamic_cast_demo();
    return 0;
}

下面为输出结果:

注意程序注释的4个地方,都是错误使用了类型转换:

第一个地方:pc = static_cast<char*>(pi) 。错误在于static_cast 不能在基本类型指针之间相互转换。

第二个地方:int z = const_cast<int>(x)。错误在于const_cast强制转换的目标类型必须是指针或引用。

第三个地方:c = reinterpret_cast<char>(i)。错误在于 const_cast用于指针类型间的强制转换,而不能用于基本类型。

第四个地方:char* pc = dynamic_cast<char*>(pi)。错误在于dynamic_cast需要虚函数的支持。

还有一个问题就是 x 和 y 值的问题。x 是一个真正意义上的常量,所以编译期间值确定了就是2,但是编译器要兼容 C语言,所以会给 x 在栈空间分配了4个字节的空间出来,使用 const_cast 作用于它就相当于给这 4个字节空间取了一个别名 y,令 y = 8,就相当于给这 4个字节栈空间中的 int 变量赋了一个值 8。所以打印出来的 x 和 y的地址值是一样的。

四、小结

C 方式的强制类型转换

  • 过于粗暴
  • 潜在的问题不易被发现
  • 不易在代码中定位

新式类型转换以C++ 关键字的方式出现

  • 编译器能够帮助检查潜在的问题
  • 非常方便的在代码中定位
  • 支持动态类型识别( dynamic_cast )

到此这篇关于C++简明讲解类型转换的使用与作用的文章就介绍到这了,更多相关C++ 类型转换内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++算术运算符与类型转换

    目录 1.算术运算符 2.优先级 3.类型转换 初始化和赋值时的转换 使用花括号进行转换 4.表达式中转换 5.强制类型转换 1.算术运算符 C++当中提供5种基础的算术运算符:加法.减法.乘法.除法和取模. 我们来看下代码: int a = 10, b = 3; cout << a + b << endl; // 13 cout << a - b << endl; // 7 cout << a * b << endl; // 30

  • C++的类型转换(强转)你了解吗

    目录 静态类型转换 动态类型转换 常量转换 重新解释转换 总结 静态类型转换 关键字: static_cast 1,允许内置数据类型之间的转换 char a = 'a'; double b = static_cast<double>(a); cout << b << endl;//97 return 0; <>中是转后的数据类型.()中是要转的变量名称. 2,允许子类和父类之间指针或者引用的转换 向上类型转换是安全的.(子转父) 向下类型转换是不安全的.(父

  • C/C++中数据类型转换详解及其作用介绍

    目录 概述 不同类型数据间的转换 隐式类型转换 强制类型转换 自己声明的类型转换 转换构造函数 类型转换函数 案例 应用 概述 在日常的开发中, 我们经常会用到数据类型转换, 所以我们要对数据类型转换有一定的了解. 不同类型数据间的转换 在 C++ 中, 某些标准类型的数据之间可以自动转换. 隐式类型转换 隐式类型转换: 由 C++ 编译系统自动完成的, 我们无需干预. 例如: int main() { int a = 6; a = a + 3.5; cout << a << en

  • C++ 强制类型转换详解

    目录 一.C强制转换 二.C++强制转换 1.static_cast 静态转换(编译时检查) 2.const_cast 常量转换 3.reinterpret_cast 重新解释转换 4.dynamic_cast 动态转换(运行时检查) 三.要点总结 一.C强制转换 C语言中的强制转换主要用于普通数据类型.指针的强制转换,没有类型检查,转换不安全, 语法为: (type-id)expression//转换格式1 type-id(expression)//转换格式2(基本已经不用了) 二.C++强制

  • C++类型转换详解

    目录 内置类型的转换 自定义类型转换 explicit 关键字 提醒 提问:编译器在什么时候使用Stone(double)? 转换函数 概念介绍 自动引用类型转换 缺陷 总结 C++对于内置类型有隐式或显式的类型转化,如int,double,long,char,但是,C++还有类这个概念,类是一种自定义类型,为了让类(自定义类型)达到内置类型的层次,C++对类也挺提供一些方法进行自动或者强制类型转换 C++的好多工作,在我看来就是让自定义类型能和内置类型一样简单使用.操作. 内置类型的转换 in

  • C++类型转换运算符详解

    目录 老式显式类型转换 c++的显示类型转换 为什么要有新的类型转换 具体应该使用哪种转换 static_cast运算符 dynamic_cast运算符 const_cast运算符 reinterpret_cast运算符 老式显式类型转换实际的转换方式 总结 老式显式类型转换 (类型)表达式 c风格的强制类型转换 类型(表达式) 函数式的强制类型转换 1,最开始使用的是c风格的类型转换,但是为了能够使类型转换看起来更像是一个函数调用,因此引入了函数式的类型转换.函数式的类型转换能够像使用一个函数

  • 浅谈C++类型转换几种情况

    目录 0. 类型转换的原理 1. 初始化和赋值时进行的转换 2. 以{}方式初始化时进行的转换(C++11新增) 3. 表达式中的转换 4. 传递参数时的转换 5. 强制类型转换 6. 使用auto让编译器自己推断变量类型 0. 类型转换的原理 在进行下面的学习前,我觉得有比较知道不同类型是怎么进行转换的. int a = 777777; //二进制为00000000 01110110 10101101 11110001 short b = a; //b只有2字节,从低位开始截断,只能存1010

  • C++ 的类型转换详解

    目录 一.C++ 类型转换 1.静态类型转换 1.语法格式 2.转化规则 2.重解释类型转换 1.语法格式 2.转化规则 3.常类型转换 1.语法格式 2.语法规则 3.const 常变量(补充) 4.动态类型转换 1.语法格式 总结 一.C++ 类型转换 1.静态类型转换 1.语法格式 static_cast<目标类型> (标识符) 2.转化规则 在一个方向上可以作隐式转换,在另外一个方向上就可以作静态转换. int a = 10; int b = 3; cout<<static

  • C++简明讲解类型转换的使用与作用

    目录 一.C语言中的强制类型转换 二.C语言强制类型转换存在的问题 三.C++ 中的类型转换 四.小结 一.C语言中的强制类型转换 转换的语法如下: (Type) (Expression) Type(Expression) 下面看一段C语言中粗暴的类型转换的代码: #include <stdio.h> typedef void(PF)(int); struct Point { int x; int y; }; int main() { int v = 0x12345; PF* pf = (PF

  • C语言简明讲解类型转换的使用与作用

    目录 一.类型之间的转换 二.强制类型转换 三.隐式类型转换 四.表达式中的隐式类型转换 五.小结 一.类型之间的转换 C语言中的数据类型可以进行转换 强制类型转换 隐式类型转换 二.强制类型转换 强制类型转换的语法 (Type)var_name; (Type)value; 强制类型转换的结果 目标类型能够容纳目标值:结果不变 目标类型不能容纳目标值:结果将产生截断 注意:不是所有的强制类型转换都能成功,当不能进行强制类型转换时,编译器将产生错误信息(比如将自定义数据类型转换成基本数据类型).

  • Python简明讲解filter函数的用法

    目录 一.filter函数的定义 二.filter函数实例 求一个序列中大于零的元素组成的新序列 求序列中非零数组成的新序列 求字典中大于2的键组成的新序列 求100以内既是3的倍数又是奇数的正整数 任何事情都是由量变到质变的过程,学习Python也不例外.只有把一个语言中的常用函数了如指掌了,才能在处理问题的过程中得心应手,快速地找到最优方案. 一.filter函数的定义 filter函数是Python中常用的内置函数,调用无需加载库,直接使用即可.它主要用来根据特定条件过滤迭代器中不符合条件

  • Go并发4种方法简明讲解

    一.goroutine 1.协程(Coroutine) Golang 在语言层面对并发编程进行了支持,使用了一种协程(goroutine)机制, 协程本质上是一种用户态线程,不需要操作系统来进行抢占式调度,但是又寄生于线程中,因此系统开销极小,可以有效的提高线程的任务并发性,而避免多线程的缺点.但是协程需要语言上的支持,需要用户自己实现调度器,因为在Go语言中,实现了调度器所以我们可以很方便的能过 go关键字来使用协程. func main() { for i := 0; i <10; i++

  • C语言简明讲解三目运算符和逗号表达式的使用

    目录 一.三目运算符 二.逗号表达式 三.小结 一.三目运算符 三目运算符( a ? b : c)可以作为逻辑运算的载体 规则:当 a 的值为真时,返回 b 的值:否则返回 c 的值 下面看一段代码: #include <stdio.h> int main() { int a = 1; int b = 2; int c = 0; c = a < b ? a : b; (a < b ? a : b) = 3; printf("%d\n", a); printf(&

  • C语言简明讲解队列的实现方法

    目录 前言 队列的表示和实现 队列的概念及结构 代码实现 束语 前言 大家好啊,我又双叒叕来水博客了,道路是曲折的,前途是光明的,事物是呈螺旋式上升的,事物最终的发展结果还是我们多多少少能够决定的,好啦,吹水结束,这与这篇博客的主题并没有太多联系.关于栈和队列这一板块本来是想不写(就是想偷懒),但是想了想,觉得这样不太好,关于数据结构这一块可能会有缺失,所以最终还是决定写,必须补齐这一块,恰好最近有时间写博客,所以还是写了,这篇博客将介绍队列的知识点,理解链表那一块的操作后,栈和队列的相关操作还

  • C语言简明讲解操作符++和--的使用方法

    目录 一.++与--操作符的本质 二.++与-- 操作符使用分析 三.小结 一.++与--操作符的本质 ++ 和 -- 操作符对应两条汇编指令 前置 变量自增(减)1 取变量值 后置 取变量值 变量自增(减)1 下面看一段神奇的代码: #include <stdio.h> int main() { int i = 0; int r = 0; r = (i++) + (i++) + (i++); printf("i = %d\n", i); printf("r =

  • C语言简明讲解变量的属性

    目录 一.C语言中的变量属性 二.auto 关键字 三.register 关键字 四.static 关键字 五.extern 关键字 六.小结 一.C语言中的变量属性 C语言中的变量可以有自己的属性 在定义变量的时候可以加上“属性”关键字 "属性”关键字指明变量的特有意义 语法: property type var_name; 示例: int main() { auto char i; register int j; static long k; extern double m; return

  • C语言简明讲解单引号与双引号的使用

    目录 一.单引号和双引号 二.小贴士 三.程序实例分析1 四.程序实例分析2 五.容易混淆的代码 六.小结 一.单引号和双引号 C语言中的单引号用来表示字符字面量 C语言中的双引号用来表示字符串字面量 'a'表示字符字面量,在内存中占1个字节,'a'+1表示'a'的ASCII码加1,结果为'b' "a"表示字符串字面量,在内存中占2个字节,"a"+1表示指针运算,结果指向"a"结束符'\0' 下面看一段单引号和双引号本质的代码: #include

随机推荐