C++:详解显式类型转换

简介: C++:详解显式类型转换

C++ 与 C 强制类型转换的区别

  • C 可以在任意类型之间转换,不安全;C++ 相对比较安全。
  • C 难以查询定位。C++ 易于追踪,grep -rn "cast-name"

语法形式:

cast-name <type> (expression)

1 、static_cast

基础类型间的转换

  • 基本数据类型间的转换,不能用于无关类型的转换。
  • void 指针转换成目标类型的指针,任何类型的表达式转换成 void 类型。
double d = static_cast<int>(i);             // ok, 用于基本数据类型间的转换
 int *pInt = static_cast<int*>(pVoid);       // ok,void 指针转换成目标类型的指针
 float *pFloat = static_cast<float *>(pInt);  // error,不能用于无关类型转换,不同指针类型间转换

2、dyamic_cast

用于下行转换(基类 -> 派生类),运行时动态检查。

类继承中的类型转换

  • 上行转换:派生类 -> 基类,派生类指针或引用转换成基类指针或引用,安全。
  • 下行转换:基类 -> 派生类,基类指针或引用转换成派生类指针或引用,不安全,需要动态类型检查 dyamic_cast,这是因为基类指针和引用可能指向的并不是一个子类对象。
// 同时完成类型转换和条件检查两个任务
 // 1、转换成功
 if (Derived *dp = dynamic_cast<Derived*>(bp)) {
     // 使用 dp 指向派生类对象
 }
 // 2、转换失败
 else {
     // 使用 bp 指向的基类对象
 }

3、const_cast

移除类型的 const 或 volatile 属性。将常量对象转换成非常量对象。

const int number = 100;
 int *pInt2 = const_cast<int *>(&number);  // ok,但是通过 pInt2 写值是未定义的行为 *pInt2 = 200

上述例子中提到的未定义的行为,const_cast 不是为了改变常量的值而设计的。话句话说,要修改值,一开始就应该定义为变量,何必多此一举定义为常量。const_cast 用于有函数重载的上下文中,例如:

const string &shorterString(const string &s1, const string &s2) {
     return s1.size() <= s2.size() ? s1 : s2;
 }

若对两个非常量的 string 实参调用这个函数,但是返回结果仍然是 const string 的引用。因此我们需要重载该函数,当实参不是常量的时候,返回普通引用。

string &shorterString(string &s1, string &s2) {
     // 实参强制转换成对 const 的引用,调用 shorterString 函数的 const 版本
     auto &r = shorterString(const_cast<const string&>(s1), const_cast<const string&>(s2));
     // 将返回的 const string 引用转换为普通的 string &
     return const_cast<const string&>(r);
 }

const_cast 用于函数重载,其他情况下使用则说明程序存在着某种设计缺陷。

4、reinterpret_cast

为运算对象的位模式提供较低层次上的重新解释。该运算符可以用来处理无关类型之间的转换,例如任意指针(引用)类型之间的转换。效果等同于 C 语言风格的强制类型转换。这样可能会导致未定义的行为,例如数字类型转换为指针类型。不同于 static_cast,使用 reinterpret_cast 没有安全检查,这一点要尤其小心。

相关文章
|
2月前
|
设计模式 安全 算法
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
【C/C++ 类型转换 】深入理解C++向上转型:从基础到应用
43 0
|
2月前
|
安全 编译器 程序员
特殊类设计以及C++中的类型转换
特殊类设计以及C++中的类型转换
30 2
|
2月前
|
安全 编译器 C++
【C/C++ 类型转换规则】一文了解C/C++ 中的类型转换规则,帮助你更好的编程
【C/C++ 类型转换规则】一文了解C/C++ 中的类型转换规则,帮助你更好的编程
22 0
|
2天前
|
存储 安全 编译器
C++:现代类型转换
C++:现代类型转换
21 5
|
6天前
|
编译器 C++
【C++】类与对象(static、explicit、友元、隐式类型转换、内部类、匿名对象)
【C++】类与对象(static、explicit、友元、隐式类型转换、内部类、匿名对象)
8 2
|
10天前
|
存储 编译器 C语言
【C++】C++中规范[ 类型转换标准 ] 的四种形式
【C++】C++中规范[ 类型转换标准 ] 的四种形式
|
13天前
|
安全 程序员 编译器
【C++类和对象】初始化列表与隐式类型转换
【C++类和对象】初始化列表与隐式类型转换
|
18天前
|
安全 编译器 C语言
【C++高阶(九)】C++类型转换以及IO流
【C++高阶(九)】C++类型转换以及IO流
|
2月前
|
算法 安全 编译器
【C++运算符重载】深入理解C++中的类型转换与重载
【C++运算符重载】深入理解C++中的类型转换与重载
32 0
|
2月前
|
算法 Linux 编译器
【C++ 泛型编程 进阶篇】 C++ 模版元编程 类型转换 std::decay 全面教程
【C++ 泛型编程 进阶篇】 C++ 模版元编程 类型转换 std::decay 全面教程
48 0