IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++中的类型转换 -> 正文阅读

[C++知识库]C/C++中的类型转换


类型转换即将一种数据类型转换称另外一种数据类型,C中有隐式转换和强制转换,其中强制转换使用同一转换格式去处理任意类型间的转换,而C++做为C的超集,在支持C的类型转换功能上,在强制转换上细分出四种类型转换操作符来进行强制转换,分别是static_cast, dynamic_cast, reinterpret_cast, 与const_cast。

一、C中的类型转换

1.1 隐式转换

即自动转换,由C编译器自动执行,无需程序员干预。
1 表达式中地类型提升:
表达式中如果包含几种不同地数据类型,表达式类型为当前表达式中最高类型;
比如 x+y, 一个是int,一个是float,则表达式类型为float

2 赋值时地类型转换
当赋值时两边地类型不同时,赋值运算符右边地表达式会被提升(降级)为左边数据对象地类型,即右边地数据地数据类似会被强制变成左边地数据类型,但是并不改变赋值右边原对象。

隐式转换提升有如下规则:原则尽量保持精度,即低精度(float)会向高精度(double)转换,存储空间小(char)会向空间大类型转换(int)。

1.1强制转换

强制类型转换使用强制转换运算符在程序中手动地对类型转换进行控制,强制转换由表达式和其前面用圆括号括起来地类型组成,对算术表达式和指针都可以执行强制类型转换。强制转换可以进行任意任性转换(比如除了基本类型转换,还可以用于指针转换,const指针/引用-》非const指针/引用,继承类之间转换)
1 强制转换算法表达式地类
如将float b 转换为int a : a=(int) b;
2 强制转换指针地类型
以void为例:
注意,给void指针赋值或将其与NULL作比较时,不需要执行强制类型转换,但是对其解引用或执行指针运算之前必须转成合适地类型。
int* a=(int*)malloc(size0f(int)); //malloc函数返回地是void类型指针,强制强制转换为int*;

二、C++中的类型转换

1 C++对C中类型转换的原因:

补充:C++与C地显示转换的区别
1 容易辨识:尖括号<>使得C++类型转换操作符非常容易辨识,而在编程中我们也可以搜索“_cast”来寻找类型转换,C风格的类型转换语法显然更容易被忽略,从而导致出错。
2 语义明确,C++的几种类型转换操作符语义都互不相同,而C风格的类型转换都是用一个相同的语法代替,没有进行区分,比如你可以把一个指向 const 对象的指针转换 成指向非 const 对象的指针,把一个指向基类对象的指针转换成指向一个派生类对象的 指针,这两种转换之间的差别是巨大的,但是传统的 c 语言风格的类型转换没有区分这些。并且一般类型reinterpret_cast并不能用C风格的类型转换实现(只有涉及指针的时候才可以),

2 C++中隐式转换规则:

规则总结:(同C)
-》非浮点类型从短类型到长类型
-》非浮点类型转换为浮点类型
-》低精度浮点类型转换为高精度浮点类型
-》signed类型转换到unsigned类型

3 C++中显示转换规则:

类型转换操作符说明
static_cast静态类型转换
dynamic_cast父子类之间的多态类型转换
const_cast去掉const属性
reinterpret_cast重新解释类型转换

static_cast:
(静态转换,在编译期间转换)
(1)主要用于内置数据类型之间的相互转换,

float floatnum=1.2; 
int intnum=static_cast<int>(floatnum); //static_cast<转换类型>(转换变量)

(2)也可以转换自定义类型。如果涉及到类,static_cast只能在有相互联系(继承)的类型间进行转换,且不一定包含虚函数。

class A{
};
class B : public A{
};
class C{
};

void main()
{
   A *pA = new A;
   B *pB = static_cast<B*>(pA); // 编译不会报错, B类继承于A类
   pB = new B;
   pA = static_cast<A*>(pB); // 编译不会报错, B类继承于A类
   C *pC = static_cast<C*>(pA); // 编译报错, C类与A类没有任何关系,“static_cast”: 无法从“A *”转换为“C *”
}

(3)把void类型指针转换成目标类型的指针(不安全)

dynamic_cast:
用于在类的继承层次之间进行类型转换,它既允许向上转型(Upcasting),也允许向下转型(Downcasting)。向上转型是无条件的,不会进行任何检测,所以都能成功;向下转型的前提必须是安全的,要借助 RTTI 进行检测,所有只有一部分能成功。(会在程序运行期间借助 RTTI 进行类型转换,这就要求基类必须包含虚函数)
(newType 和 expression 必须同时是指针类型或者引用类型。换句话说,dynamic_cast 只能转换指针类型和引用类型,其它类型(int、double、数组、类、结构体等)都不行。)
(1)其他三种都是编译时完成的。dynamic_cast是运行时处理的,运行时要进行类型检查。
(2)不能用于内置基本数据类型间的强制转换。例如:

double dValue = 12.12;
int nDValue = dynamic_cast<int>(dValue); 
// error C2680 : “int” : dynamic_cast的目标类型无效。目标类型必须是指向已定义类的指针或引用

(3)使用dynamic_cast进行转换时,基类中一定要有虚函数,否则编译不通过。
需要有虚函数的原因:类中存在虚函数,就说明它有想要让基类指针或引用指向派生类对象的必要,此时转换才有意义。
由于运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表中,只有定义了虚函数的类才有虚函数表。
(4)dynamic_cast转换若成功,返回的是指向类的指针或引用;若失败则会返回NULL。
(5)在类的转换时,在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的。
在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。
向上转换即为指向子类对象的向上转换,即将子类指针转化父类指针。
向下转换的成败取决于将要转换的类型,即要强制转换的指针所指向的对象实际类型与将要转换后的类型一定要相同,否则转换失败。

#include<iostream>
class Animal {
public:
	virtual void cry() = 0;
};
class Dog : public Animal
{
public:
	virtual void cry()
	{
		std::cout << "旺旺" << std::endl;
	}
	void dohome()
	{
		std::cout << "看家" << std::endl;
	}
};
class Cat : public Animal
{
public:
	virtual void cry()
	{
		std::cout << "喵喵" << std::endl;
	}
	void dohome()
	{
		std::cout << "抓老鼠" << std::endl;
	}
};

int main()
{
	Animal* base = NULL;
	base = new Cat();
	base->cry();

	//?用于将?父类指针转换成?子类,
	Dog	*pDog = dynamic_cast<Dog*>(base); //此时转换时失败的,因为父类指针现在指向的对象是猫,所以转换狗是失败的。
	                                      //转换失败返回空(NULL)
	if (pDog != NULL)
	{
		pDog->cry();
		pDog->dohome();
	}

	Cat* pCat = dynamic_cast<Cat*>(base); //此时转换成功,成功将父类指针转换成子类指针
	if (pCat != NULL)
	{
		pCat->cry();
		pCat->dohome();
	}

	system("pause");
	return 0;
}


const_cast:

const_cast的作用:const_cast 目标类型只能是引用或者指针
一、常量指针 被强转为 非常量指针,且仍然指向原来的对象;
二、常量引用 被强转为 非常量引用,且仍然指向原来的对象;
三、常量对象 被强转为 非常量对象。

reinterpret_cast:

有着与C风格的强制转换同样的能力。
它可以转化任何内置的数据类型为其他任何的数据类型,也可以转化任何指针类型为其他的类型。
它甚至可以转化内置的数据类型为指针,无须考虑类型安全或者常量的情形。不到万不得已绝对不用。
reinterpret_cast可以做任何类型的转换,不过不对转换结果保证,容易出问题。
注意:为什么不用C的强制转换:C的强制转换表面上看起来功能强大什么都能转,但是转换不够明确,不能进行错误检查,容易出错。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:13:43  更:2022-10-17 12:15:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 8:48:22-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码