searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

C++的四种强制类型转换

2023-07-25 01:40:43
9
0

     C风格的强制转换(Type Cast)容易理解,不管什么类型的转换都可以使用使用下面的方式。

 
Type a = (NewType)b; 
 

      当然,C++也是支持C风格的强制转换,但是C风格的强制转换可能带来一些隐患,让一些问题难以察觉。所以C++提供了一组可以用在不同场合的强制转换的函数。

      在C++中,我们可以使用四种强制类型转换操作符来进行类型转换。

1. 静态转换(static_cast): 静态转换是最常用的强制类型转换方式,用于一般类型的隐式转换。它可以用于类层次结构中基类和派生类之间的相互转换,也可以用于不同类型之间的转换(例如数字类型之间的转换)。

  • 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。不管是否发生多态,父子之间互转时,编译器都不会报错。

        进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;

        进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的,但是编译器不会报错。

  • 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
  • 把空指针转换成目标类型的空指针。
  • 把任何指针类型转换成空指针类型。
  • 可以对普通数据的const和non_const进行转换,但不能对普通数据取地址后的指针进行const添加和消去。
  • 无继承关系的自定义类型,不可转换,不支持类间交叉转换。

代码示例:

int num1 = 10;
double num2 = static_cast<double>(num1); // 将int类型num1转换为double类型

2. 动态转换(dynamic_cast): 动态转换主要用于类层次结构中基类和派生类之间的转换。它在运行时检查转换的有效性,如果无效则返回null指针(对于指针类型)或抛出std::bad_cast异常(对于引用类型)。

动态转换的类型和操作数必须是完整类类型或空指针、空引用,只能用于类间转换,支持类间交叉转换,不能操作普通数据。

主要用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换,

  • 进行上行转换(把派生类的指针或引用转换成基类表示)是安全的,允许转换;
  • 进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的,不允许转化,编译器会报错;
  • 发生多态时,允许互相转换。
  • 无继承关系的类之间也可以相互转换,类之间的交叉转换。
  • 如果dynamic_cast语句的转换目标是指针类型并且失败了,则结果为0。如果转换目标是引用类型并且失败了,则dynamic_cast运算符将抛出一个std::bad_cast异常

代码示例:

class Animal { ... };
class Dog : public Animal { ... };
Animal* animalPtr = new Dog();
Dog* dogPtr = dynamic_cast<Dog*>(animalPtr); // 将基类指针转换为派生类指针

3. (reinterpret_cast): reinterpret_cast可以将一个指针转换为任意其他类型的指针,也可以将一个整数类型转换为任意其他类型的指针。这种转换是非常危险的,因为它完全依赖于底层的硬件和编译器的实现。 代码示例:

int* numPtr = new int(10);
char* charPtr = reinterpret_cast<char*>(numPtr); // 将int指针转换为char指针

4. 常量转换(const_cast): 常量转换主要用于去除指针或引用的const属性,或者用于添加const属性。它在进行类型转换时并不会进行运行时检查。 const_cast用于强制去掉不能被修改的常数特性,其去除常量性的对象一般为指针或引用。

用法:const_cast<new type>(exp)
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, new_type和expression的类型是一样的。
常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象。

代码示例:

const int num = 10;
int* mutableNumPtr = const_cast<int*>(&num); // 去除指针的const属性
*mutableNumPtr = 20; // 修改num的值

 

PS:需要注意的是,在进行类型转换时要尽量避免使用reinterpret_cast,因为它的安全性较低并且不可移植。始终确保转换的合法性,并在可能的情况下优先选择静态转换和动态转换。

0条评论
0 / 1000
w****n
3文章数
0粉丝数
w****n
3 文章 | 0 粉丝
w****n
3文章数
0粉丝数
w****n
3 文章 | 0 粉丝
原创

C++的四种强制类型转换

2023-07-25 01:40:43
9
0

     C风格的强制转换(Type Cast)容易理解,不管什么类型的转换都可以使用使用下面的方式。

 
Type a = (NewType)b; 
 

      当然,C++也是支持C风格的强制转换,但是C风格的强制转换可能带来一些隐患,让一些问题难以察觉。所以C++提供了一组可以用在不同场合的强制转换的函数。

      在C++中,我们可以使用四种强制类型转换操作符来进行类型转换。

1. 静态转换(static_cast): 静态转换是最常用的强制类型转换方式,用于一般类型的隐式转换。它可以用于类层次结构中基类和派生类之间的相互转换,也可以用于不同类型之间的转换(例如数字类型之间的转换)。

  • 用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换。不管是否发生多态,父子之间互转时,编译器都不会报错。

        进行上行转换(把派生类的指针或引用转换成基类表示)是安全的;

        进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的,但是编译器不会报错。

  • 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。这种转换的安全性也要开发人员来保证。
  • 把空指针转换成目标类型的空指针。
  • 把任何指针类型转换成空指针类型。
  • 可以对普通数据的const和non_const进行转换,但不能对普通数据取地址后的指针进行const添加和消去。
  • 无继承关系的自定义类型,不可转换,不支持类间交叉转换。

代码示例:

int num1 = 10;
double num2 = static_cast<double>(num1); // 将int类型num1转换为double类型

2. 动态转换(dynamic_cast): 动态转换主要用于类层次结构中基类和派生类之间的转换。它在运行时检查转换的有效性,如果无效则返回null指针(对于指针类型)或抛出std::bad_cast异常(对于引用类型)。

动态转换的类型和操作数必须是完整类类型或空指针、空引用,只能用于类间转换,支持类间交叉转换,不能操作普通数据。

主要用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换,

  • 进行上行转换(把派生类的指针或引用转换成基类表示)是安全的,允许转换;
  • 进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的,不允许转化,编译器会报错;
  • 发生多态时,允许互相转换。
  • 无继承关系的类之间也可以相互转换,类之间的交叉转换。
  • 如果dynamic_cast语句的转换目标是指针类型并且失败了,则结果为0。如果转换目标是引用类型并且失败了,则dynamic_cast运算符将抛出一个std::bad_cast异常

代码示例:

class Animal { ... };
class Dog : public Animal { ... };
Animal* animalPtr = new Dog();
Dog* dogPtr = dynamic_cast<Dog*>(animalPtr); // 将基类指针转换为派生类指针

3. (reinterpret_cast): reinterpret_cast可以将一个指针转换为任意其他类型的指针,也可以将一个整数类型转换为任意其他类型的指针。这种转换是非常危险的,因为它完全依赖于底层的硬件和编译器的实现。 代码示例:

int* numPtr = new int(10);
char* charPtr = reinterpret_cast<char*>(numPtr); // 将int指针转换为char指针

4. 常量转换(const_cast): 常量转换主要用于去除指针或引用的const属性,或者用于添加const属性。它在进行类型转换时并不会进行运行时检查。 const_cast用于强制去掉不能被修改的常数特性,其去除常量性的对象一般为指针或引用。

用法:const_cast<new type>(exp)
该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, new_type和expression的类型是一样的。
常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象。

代码示例:

const int num = 10;
int* mutableNumPtr = const_cast<int*>(&num); // 去除指针的const属性
*mutableNumPtr = 20; // 修改num的值

 

PS:需要注意的是,在进行类型转换时要尽量避免使用reinterpret_cast,因为它的安全性较低并且不可移植。始终确保转换的合法性,并在可能的情况下优先选择静态转换和动态转换。

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0