C++运算符:类型转换规则
一. 隐式类型转换(自动类型转换)
1. 不同算术类型间的转换
在表达式中,如果不同类型的操作数混合使用,C++会自动进行一些类型转换,通常是将低精度类型转换为高精度类型。例如,在int和double混合的表达式中,int类型会自动转换为double类型。
int num1 = 5; double num2 = 3.14; double result = num1 + num2; // 这里num1会自动转换为double类型(值为5.0),然后进行加法运算
2. 赋值时的类型转换
当把一个表达式的值赋给一个变量时,如果表达式的类型与变量类型不一致,会进行隐式转换。例如,把int类型的值赋给double类型变量是允许的,会自动进行转换。
int num3 = 10; double num4; num4 = num3; // num3的值10被转换为10.0后赋给num4
3. 函数调用时的类型转换
在函数调用过程中,如果实参类型与形参类型不完全匹配,但可以进行隐式转换,那么会自动进行转换。例如,函数形参为double类型,而实参为int类型时。
void printValue(double num) { std::cout << num << std::endl; } int num5 = 7; printValue(num5); // num5会被转换为double类型后传递给printValue函数
4. 转换规则总结
基本的转换顺序是:char、signed char、unsigned char、short、unsigned short类型会转换为int类型;如果int类型不足以表示所有的值(例如unsigned short的值范围大于int的正值范围),则转换为unsigned int类型;然后int或unsigned int会转换为long或unsigned long类型;最后,如果有double类型参与运算,则float类型会转换为double类型。
二. 显式类型转换(强制类型转换)
1. C-style强制类型转换
语法:(type) expression,其中type是要转换的目标类型,expression是要转换的表达式。例如:
double num6 = 3.14; int num7 = (int)num6; // 将double类型的num6强制转换为int类型,结果num7为3(小数部分被截断)
2. static_cast转换
用于基本类型之间的转换,以及具有继承关系的类之间的转换(向上转型是安全的,向下转型需要谨慎)。
基本类型转换示例:
int num8 = 10; double num9 = static_cast<double>(num8); // 将int类型的num8转换为double类型
类的向上转型示例(假设Derived类继承自Base类):
Derived d; Base* b = static_cast<Base*>(&d); // 将Derived类的指针转换为Base类的指针(向上转型)
3. dynamic_cast转换
主要用于具有继承关系的类之间的转换,特别是向下转型(从基类指针或引用转换为派生类指针或引用)。它在运行时进行类型检查,如果转换不安全(例如,基类指针实际上并不指向要转换的派生类对象),则返回nullptr(对于指针类型)或抛出std::bad_cast异常(对于引用类型)。
假设Derived类继承自Base类:
Base* basePtr = new Derived(); Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); if (derivedPtr!= nullptr) { // 转换成功,可以安全地使用derivedPtr }
4. const_cast转换
用于去除或添加const或volatile限定符。需要注意的是,去除const限定符后修改对象的值可能会导致未定义行为,如果对象本身是定义为const的。
例如:
const int num10 = 5; int& num11 = const_cast<int&>(num10); // 去除了num10的const限定符,但修改num11的值是不安全的行为
5. reinterpret_cast转换
用于进行一些比较底层的、依赖于具体实现的类型转换,例如在指针类型和整数类型之间进行转换,或者不同指针类型之间的转换(这种转换是非常危险的,因为它可能会导致程序出现难以预料的错误)。
例如:
int num12 = 10; void* voidPtr = reinterpret_cast<void*>(&num12); int* num13 = reinterpret_cast<int*>(voidPtr); // 在int指针和void指针之间进行转换