【C++】类型转换与运算符
在实际开发中,对数据进行类型转换满足特定需求是比较常见的操作,这篇帖子用来记录类型转换的相关知识。
隐式类型转换
- 基本数据类型之间的自动转换
int i = 10;
double d = i; // 整数类型隐式转换为浮点数类型
- 派生类对象指针或者引用向基类对象或者指针引用的转换
class Base {};
class Derived : public Base {};
Derived derivedObj;
Base* basePtr = &derivedObj; // 派生类对象指针隐式转换为基类对象指针
- 含有单参数的类对象到期其目标类型的转换
class A {
public:
A(int x) : val(x) {}
private:
int val;
};
void func(double d) {
// ...
}
int main() {
A a = 5; // 含有单参数构造函数的类对象隐式转换为目标类型
func(a); // 调用 func 函数,将 A 类对象转换为 double 类型
return 0;
}
explicit关键字
禁止隐式转换只允许显示转换
#include <iostream>
class MyClass {
public:
explicit MyClass(int x) : val(x) {}
int getValue() const {
return val;
}
private:
int val;
};
void printValue(const MyClass& obj) {
std::cout << "Value: " << obj.getValue() << std::endl;
}
int main() {
// MyClass obj = 10; // 编译错误:不能进行隐式类型转换
MyClass obj(10); // 显式调用构造函数进行对象的创建
printValue(obj);
return 0;
}
显示类型转换
显示类型转换是在代码中显式地使用类型转换操作符来执行类型转换的过程。在 C++ 中,可以使用四种不同的类型转换操作符来进行显示类型转换,它们分别是 static_cast、dynamic_cast、const_cast 和 reinterpret_cast。
static_cast
static_cast 主要用于进行编译时的静态类型转换。它可以用于基本数据类型之间的转换、指针之间的转换,以及类层次结构中的向上转换和向下转换。
基本数据类型之间的转换
int i = 10;
double d = static_cast<double>(i); // 将整数类型转换为浮点数类型
指针之间的转换
int* p = new int(42);
void* vp = static_cast<void*>(p); // 将指向 int 类型的指针转换为指向 void 类型的指针
类层次结构中的向上转换和向下转换
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {};
Base* basePtr = new Derived();
Derived* derivedPtr = static_cast<Derived*>(basePtr); // 向下转换
应用场景:
在进行不相关但相关的类型之间的转换时,例如整数到浮点数的转换。
在进行指针之间的转换时,例如将指向派生类对象的基类指针转换为指向派生类对象的指针。
在进行基本数据类型到指针类型的转换时,例如将整数转换为指针类型。
在进行非多态类型的类指针之间的转换时,例如将指向基类的指针转换为指向派生类的指针。
dynamic_cast
dynamic_cast 主要用于在运行时进行动态类型转换。它只能用于类层次结构中,并且被转换的类型必须具有虚函数。
类层次结构中的向下转换
class Base {
public:
virtual ~Base() {}
};
class Derived : public Base {};
Base* basePtr = new Derived();
Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // 向下转换
应用场景:
在进行类层次结构中的向下转换时,即将基类指针或引用转换为派生类指针或引用。
在需要进行安全的运行时类型检查时,以避免发生不安全的类型转换。
const_cast
用途: const_cast 用于去除指针或引用的 const 或 volatile 修饰符。
去除 const 修饰符
const int i = 10;
int& ref = const_cast<int&>(i); // 去除 const 修饰符
去除 volatile 修饰符
volatile int j = 20;
int* ptr = const_cast<int*>(&j); // 去除 volatile 修饰符
应用场景:
在需要修改指向 const 对象的指针或引用时使用。
在需要修改指向 volatile 对象的指针或引用时使用。
reinterpret_cast
用途: reinterpret_cast 用于将指针或引用类型转换为另一种不相关的指针或引用类型。
指针类型之间的转换
int* p = new int(42);
double* dp = reinterpret_cast<double*>(p); // 将指向 int 类型的指针转换为指向 double 类型的指针
应用场景:
在进行指针类型之间的不相关的类型转换时使用。
在进行类型转换时,不需要进行类型检查,且允许在不同类型之间进行二进制位的重新解释。
在涉及底层系统编程或者与硬件交互的场景中使用,例如将指向一个数据结构的字节流转换为特定类型的指针。
总结:
static_cast 用于通用的静态类型转换,适用于大部分场景。
dynamic_cast 用于类层次结构中的安全的向上或向下转换,需要运行时类型信息。
const_cast 用于去除指针或引用的 const 或 volatile 修饰符。
reinterpret_cast 用于不相关类型之间的指针转换或者进行低层次的类型转换,需要特别小心使用,可能会导致未定义行为。