衡水稳定的网络建站,微信开发者版是什么意思,公司展览厅设计,WordPress怎么两个标题系列文章目录
04 C中的四种强制类型转换 目录
系列文章目录
文章目录
前言
一、静态转换#xff08;Static Cast#xff09;
二、动态转换#xff08;Dynamic Cast#xff09;
三、常量转换#xff08;Const Cast#xff09;
四、重新解释转换#xff08;Reinte…系列文章目录
04 C中的四种强制类型转换 目录
系列文章目录
文章目录
前言
一、静态转换Static Cast
二、动态转换Dynamic Cast
三、常量转换Const Cast
四、重新解释转换Reinterpret Cast
总结 前言
类型转换是将一个数据类型的值转换为另一种数据类型的值。
C 中有四种类型转换静态转换、动态转换、常量转换和重新解释转换。
隐式类型转换是编译器自动隐式进行的需要在代码中体现而显示类型转换由程序员明确指定。
C支持C风格的强制转换但是C风格的强制转换可能带来一些隐患让一些问题难以发现。
所以C提供了一组适用于不同场景的强制转换的函数
static_castdynamic_castconst_castreinterpret_cast
下面对这四种转换操作的适用场景分别进行说明。 一、静态转换Static Cast 静态转换是将一种数据类型的值强制转换为另一种数据类型的值。 静态转换通常用于比较类型相似的对象之间的转换例如将 int 类型转换为 float 类型。 静态转换不进行任何运行时类型检查因此可能会导致运行时错误。 下面是一个例子将int类型转换为float类型
int main()
{int a 10;float b static_castfloat(a); // 静态将int类型转换为float类型cout typeid (a).name() endl;cout typeid (b).name() endl;}
输出结果为
int
float
需要注意的是这里即使我们写int a a;程序也可以编译过去所以我们要注意使用。 二、动态转换Dynamic Cast C中的动态转换dynamic_cast是一种类型转换运算符用于在运行时将指向父类的指针或引用转换为指向其派生类的指针或引用。 使用动态转换时必须满足以下两个条件之一 目标类型是源类型的公共派生类。源类型是指向目标类型的指针或引用。 如果以上条件不满足则转换将失败并返回空指针或引用。 下面是一个示例
#include iostream
using namespace std;class Animal {
public:virtual void makeSound() {cout Unknown animal sound. endl;}
};class Cat : public Animal {
public:void makeSound() {cout Meow! endl;}
};class Dog : public Animal {
public:void makeSound() {cout Woof! endl;}
};int main() {// 两个指针变量 a 和 b 分别指向一个 Cat 类型对象和一个 Dog 类型对象。Animal* a new Cat;Animal* b new Dog;// 使用动态类型转换将指针 a 转换为指向 Cat 类型的指针 c。Cat* c dynamic_castCat*(a);// 判断指针 c 是否为 nullptr如果不是则调用 Cat 类的成员函数 makeSound() 输出动物的叫声// 否则输出 “Cannot convert Animal* to Cat*.”。if (c) {c-makeSound();}else {cout Cannot convert Animal* to Cat*. endl;}// 使用动态类型转换将指针 b 转换为指向 Cat 类型的指针 c。c dynamic_castCat*(b);if (c) {c-makeSound();}else {cout Cannot convert Animal* to Cat*. endl;}return 0;
}输出结果为
Meow!
Cannot convert Animal* to Cat*. 在此示例中我们创建了两个Animal类型的指针一个指向Cat对象另一个指向Dog对象。接下来我们使用Dynamic Cast将这些指针转换为指向Cat对象的指针。第一个转换将成功因为指针a指向的是Cat对象。第二个转换失败因为指针b指向的是Dog对象无法转换为Cat对象。 注意动态转换在代码中经常用于将基类对象转换为派生类对象以便使用派生类的成员函数和成员变量。需要注意的是使用动态转换时应该注意类型安全并避免滥用。 三、常量转换Const Cast 常量转换用于将 const 类型的对象转换为非 const 类型的对象。 常量转换只能用于转换掉 const 属性不能改变对象的类型 下面是一个常量转换const_cast的代码示例
#include iostream
using namespace std;void printValue(int value) {cout The value is: value endl;
}int main() {const int value 10;const int* ptr value;// 将 ptr 转换为非常量指针int* mutablePtr const_castint*(ptr);// 修改指针所指向的值*mutablePtr 20;// 调用函数输出修改后的值printValue(value);return 0;
}在这个示例中我们首先定义了一个常量值 value 和一个指向该值的常量指针 ptr。然后我们使用 const_cast 将 ptr 转换为非常量指针 mutablePtr。接着我们通过 mutablePtr 修改了指针所指向的值为 20。最后我们调用函数 printValue 输出修改后的值即 20。
需要注意的是这里的常量指针指向的值并没有真正变为可修改的只是通过 const_cast 绕过了编译器的常量性检查。因此使用 const_cast 必须非常小心避免对常量值进行意外的修改。
四、重新解释转换Reinterpret Cast C中的重新解释转换Reinterpret Cast是一种类型转换操作用于将一个指针或引用转换为另一种不同类型的指针或引用而不考虑它的原始类型和值。它主要用于将一个对象的位模式重新解释为另一个对象的位模式。由于这种类型转换没有进行类型检查因此使用起来比较危险应该谨慎使用。 以下是一个重新解释转换reinterpret_cast的代码
#include iostream
using namespace std;int main() {int num 100;double* pDouble reinterpret_castdouble*(num);cout num num endl;cout pDouble *pDouble endl;return 0;
}在这个例子中我们将一个整数类型的变量num的地址强制类型转换为了双精度浮点数类型的指针。这个强制类型转换的意义是告诉编译器将num的二进制数据按照双精度浮点数类型的格式重新解释。 当我们输出pDouble的值时由于在编译器中整数和浮点数的存储方式一般是不同的因此pDouble的值很可能会是随机垃圾数据。
因此我们在实际开发中很少使用reinterpret_cast除非我们确实需要进行一些非常特殊的操作。 总结
综上在使用强制类型转换时需要首先考虑清楚使用目的
static_cast基本类型转换低风险dynamic_cast类层次间的上行转换或下行转换低风险const_cast去 const 属性低风险reinterpret_cast转换不相关的类型高风险。