C++类型强转

2024-01-01 04:38
文章标签 c++ 类型 强转

本文主要是介绍C++类型强转,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

数据类型强转,可以用C风格的强转和C++下的运算符强转。
数据类型强转包括:内置对象和内置对象之间,自定义对象和自定义对象之间,指针(引用)之间,指针与对象之间,对象与指针之间。

经过测试,具体强转规则有:
1).C风格强转:C++把它保留了下来,以利于兼容;可“对应”一切C++运算符强转;有几种情况不能强转:自定义类型对象(无继承关系)之间不能强转;不能将基类对象转换为子类对象)。

2).static_cast: 一般的强转都可以,除了C风格强转不能转的情况之外,还有: 1.不能把没有继承关系的类的指针之间进行转换; 2.不能把对象转换为指针,指针转换为对象。
3).reinterpret_cast: 1.只能用于指针和引用;不能用于对象之间;2.内置类型,(一定情况下)可以把对象转换为指针,指针转换为对象;继承关系类之间不可以;3.任何自定义类型不可以进行从指针到对象,对象到指针的转换。

4).dynamic_cast: 1. 只能用于继承关系的指针和引用 2. 只能将子类型指针转换为基类型指针。
5).const_cast: 1. 只能用于指针和引用 2. 将const指针转化为普通指针(除C风格转换外),只能用const_cast 。

#include <iostream>
using namespace std;struct sCast1
{int a;int b;
};struct sCast2
{int a;char b;char c;
};class cFather
{public:int a, b;
};class cSon:public cFather
{public:int c;char d;
};//C风格的强转对应所有C++ name_cast<T*>(var)强转。
//1.数字类型和数字类型、指针和指针之间可以相互转换;
//2.内置类型,(一定情况下)可以把对象转换为指针,指针转换为对象;
//3.不能把一个类型(对象)转换成其他任何类型(对象);
//4.但是子类对象可以转换为父类对象。
void test_Cstyle()
{char x = 'a';int y0 = x;int y1 = (int)x;int y2 = int(x); //这种转换是C++的      int *y3 = (int*)x; //对象到指针int y4 = (int)y3; //指针到对象sCast1 sc1;//sCast2 sc2 = (sCast2)sc1;  //错误,不能把一个结构类型(对象)转换成其他任何类型(对象)。sCast2 *sc2 = (sCast2*)&sc1;  //指针之间可以互相转换cSon cs00;cFather cf00 = (cFather)cs00;    cFather *cf01 = (cFather*)&cs00;cFather cf10;//cSon cs10 = (cSon)cf10; //错误,不能将父对象转换为子对象cSon *cs11 = (cSon*)&cf10;
}//1.不能把没有继承关系的类之间进行指针转换
//2.不能把对象转换为指针,指针转换为对象;
void test_Static_cast()
{char x = 'a';int y0 = static_cast<int>(x);//int *y3 = static_cast<int*>(x); //错误,对象到指针//int y4 = static_cast<int>(y3); //错误,指针到对象sCast1 sc1;//sCast2 sc2 = static_cast<sCast2>(sc1);  //错误,不能转换//sCast2 *sc2 = static_cast<sCast2*>(&sc1);  //错误,指针之间也不能用static_cast进行转换cSon cs00;cFather cf00 = static_cast<cFather>(cs00);    cFather *cf01 = static_cast<cFather*>(&cs00);cFather cf10;//cSon cs10 = static_cast<cSon>(cf10); //错误,不能将父对象转换为子对象cSon *cs11 = static_cast<cSon*>(&cf10);
}//1.只能用于指针和引用;不能用于对象之间;
//2.内置类型,(一定情况下)可以把对象转换为指针,指针转换为对象;继承关系类之间不可以;
//3.任何自定义类型不可以进行从指针到对象,对象到指针的转换
void test_Reinterpret_cast()
{char x = 'a';int *y = reinterpret_cast<int*>(x); //对象到指针int z = reinterpret_cast<int>(y); //指针到对象sCast1 sc1;//sCast2 sc2 = reinterpret_cast<sCast2>(sc1);  //错误,不能用于对象之间sCast2 *sc2 = reinterpret_cast<sCast2*>(&sc1);  cSon cs00;//cFather cf00 = reinterpret_cast<cFather>(cs00);    //错误,不能用于对象之间cFather *cf01 = reinterpret_cast<cFather*>(&cs00);//cFather *cf02 = reinterpret_cast<cFather*>(cs00);cFather cf10;//cSon cs10 = reinterpret_cast<cSon>(cf10); //错误,不能将父对象转换为子对象cSon *cs11 = reinterpret_cast<cSon*>(&cf10);//cSon *cs12 = reinterpret_cast<cSon*>(cs00); //错误,不能用于自定义对象到指针//cSon cs13 = reinterpret_cast<cSon>(&cs00);  //错误,不能用于自定义指针到对象
}//1. 只能用于继承关系的指针和引用
//2. 只能将子类型指针转换为父类型指针
void test_Dynamic_cast()
{char x = 'a';//int *y = dynamic_cast<int*>(x); //错误,对象到指针//int z = dynamic_cast<int>(y); //错误,指针到对象sCast1 sc1;//sCast2 sc2 = dynamic_cast<sCast2>(sc1);  //sCast2 *sc2 = dynamic_cast<sCast2*>(&sc1);  cSon cs00;//cFather cf00 = dynamic_cast<cFather>(cs00);    cFather *cf01 = dynamic_cast<cFather*>(&cs00);  //只能用于将子类指针转换为父类指针//cFather *cf02 = dynamic_cast<cFather*>(cs00);cFather cf10;//cSon cs10 = dynamic_cast<cSon>(cf10); //cSon *cs11 = dynamic_cast<cSon*>(&cf10);//cSon *cs12 = dynamic_cast<cSon*>(cs00);//cSon cs13 = dynamic_cast<cSon>(&cs00);
}//1. 只能用于指针和引用
//2. 将const指针转化为普通指针,只能用const_cast
void test_Const_cast()
{int a = 1;//int b = const_cast<int>(a); //错误,不能用于对象int *c =  const_cast<int*>(&a);*c = 2;const int *d = &a;  //常量指针//*d = 10;          //常量不能赋值int *e1 = const_cast<int*>(d);         //int *e2 = reinterpret_cast<int*>(d);  //错误, const指针转化为普通指针,只能用const_cast//int *e3 = static_cast<int*>(d);//int *e4 = dynamic_cast<int*>(d);*e1 = 20;cout<<a<<endl;cout<<*e1<<endl;char x = 'a';//int y0 = const_cast<int>(x);//int *y = const_cast<int*>(x); //错误,对象到指针//int z = const_cast<int>(y); //错误,指针到对象sCast1 sc1;sc1.a = 1;sc1.b = 2;//sCast2 sc2 = const_cast<sCast2>(sc1);  //错误,不能转换//sCast2 *sc2 = const_cast<sCast2*>(&sc1);  //错误, cSon cs00;cs00.a = 1;cs00.b = 2;cs00.c = 3;//cFather cf00 = const_cast<cFather>(cs00);    //cFather *cf01 = const_cast<cFather*>(&cs00);//cFather *cf02 = const_cast<cFather*>(cs00);cFather cf10;//cSon cs10 = const_cast<cSon>(cf10); //错误,//cSon *cs11 = const_cast<cSon*>(&cf10);//cSon *cs12 = const_cast<cSon*>(cs00);//cSon cs13 = const_cast<cSon>(&cs00);const sCast1 sc11 = sc1;//sCast2 sc2 = const_cast<sCast2>(sc11);  //错误,不能转换//sCast2 *sc2 = const_cast<sCast2*>(&sc11);  //指针之间也不能用static_cast进行转换  const cSon cs01 = cs00;//cFather cf00 = const_cast<cFather>(cs01);    //cFather *cf01 = const_cast<cFather*>(&cs01);//cFather *cf02 = const_cast<cFather*>(cs01);//const cFather cf11;//cSon cs10 = const_cast<cSon>(cf11); //错误,不能将子对象转换为父对象//cSon *cs11 = const_cast<cSon*>(&cf11);//cSon *cs12 = const_cast<cSon*>(cf11);//cSon cs13 = const_cast<cSon>(&cf11);}int main()
{test_Cstyle();test_Static_cast();test_Reinterpret_cast();test_Dynamic_cast();test_Const_cast();return 1;
}


 

 

这篇关于C++类型强转的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/558193

相关文章

C++ 右值引用(rvalue references)与移动语义(move semantics)深度解析

《C++右值引用(rvaluereferences)与移动语义(movesemantics)深度解析》文章主要介绍了C++右值引用和移动语义的设计动机、基本概念、实现方式以及在实际编程中的应用,... 目录一、右值引用(rvalue references)与移动语义(move semantics)设计动机1

C++ move 的作用详解及陷阱最佳实践

《C++move的作用详解及陷阱最佳实践》文章详细介绍了C++中的`std::move`函数的作用,包括为什么需要它、它的本质、典型使用场景、以及一些常见陷阱和最佳实践,感兴趣的朋友跟随小编一起看... 目录C++ move 的作用详解一、一句话总结二、为什么需要 move?C++98/03 的痛点⚡C++

详解C++ 存储二进制数据容器的几种方法

《详解C++存储二进制数据容器的几种方法》本文主要介绍了详解C++存储二进制数据容器,包括std::vector、std::array、std::string、std::bitset和std::ve... 目录1.std::vector<uint8_t>(最常用)特点:适用场景:示例:2.std::arra

C++构造函数中explicit详解

《C++构造函数中explicit详解》explicit关键字用于修饰单参数构造函数或可以看作单参数的构造函数,阻止编译器进行隐式类型转换或拷贝初始化,本文就来介绍explicit的使用,感兴趣的可以... 目录1. 什么是explicit2. 隐式转换的问题3.explicit的使用示例基本用法多参数构造

C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解

《C++,C#,Rust,Go,Java,Python,JavaScript的性能对比全面讲解》:本文主要介绍C++,C#,Rust,Go,Java,Python,JavaScript性能对比全面... 目录编程语言性能对比、核心优势与最佳使用场景性能对比表格C++C#RustGoJavapythonjav

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

C++打印 vector的几种方法小结

《C++打印vector的几种方法小结》本文介绍了C++中遍历vector的几种方法,包括使用迭代器、auto关键字、typedef、计数器以及C++11引入的范围基础循环,具有一定的参考价值,感兴... 目录1. 使用迭代器2. 使用 auto (C++11) / typedef / type alias

C# WebAPI的几种返回类型方式

《C#WebAPI的几种返回类型方式》本文主要介绍了C#WebAPI的几种返回类型方式,包括直接返回指定类型、返回IActionResult实例和返回ActionResult,文中通过示例代码介绍的... 目录创建 Controller 和 Model 类在 Action 中返回 指定类型在 Action

C++ scoped_ptr 和 unique_ptr对比分析

《C++scoped_ptr和unique_ptr对比分析》本文介绍了C++中的`scoped_ptr`和`unique_ptr`,详细比较了它们的特性、使用场景以及现代C++推荐的使用`uni... 目录1. scoped_ptr基本特性主要特点2. unique_ptr基本用法3. 主要区别对比4. u

C++11中的包装器实战案例

《C++11中的包装器实战案例》本文给大家介绍C++11中的包装器实战案例,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录引言1.std::function1.1.什么是std::function1.2.核心用法1.2.1.包装普通函数1.2.