1.算术转换
算术转换是非常经典的隐式转换发生的场景,当进行算术运算时,不同类型的操作数会自动转换成相同的类型,例如:
int i = 3;
double j = i + 3.14; // i被隐式转换为double
2.初始化转换
当初始化操作中,右侧的值会被隐式转换成左侧变量的类型,例如:
int x = 3.14; // 3.14被隐式转换为int
3.函数调用转换
在函数调用时,如果提供的实参类型与形参类型不匹配,编译器可能会隐式转换实参,例如:
void Print(const char* str) {
std::cout << str << std::endl;
}
Print(3); // 3被隐式转换为const char*
4.数组到指针的转换
在下面及大多数情况下,数组名会被隐式转换为指向数组第一个元素的指针,例如:
int arr[3];
int* ptr = arr; // arr被隐式转换为int*
5.类中的构造函数允许隐式转换
假设有一个简单的类MyNum
,它有一个接受int
参数的构造函数,这个构造函数将允许从int
到MyNum
对象的隐式转换,例如:
#include <iostream>
using namespace std;
class MyNum {
public:
//此为构造函数,与类同名,作用是初始化num的值为num_
MyNum(int num_) : num(num_) {}
//输出函数
void display() {
cout << "num is: " << num << endl;
}
private:
int num;
};
int main() {
// 隐式转换
// 这里发生了隐式转换,将int转换为MyNum对象
MyNum i = 10;
i.display(); // 输出
return 0;
}
当然,也可以避免隐式转换,要在构造函数前面加上关键字explicit:
explicit MyNum(int num_) : num(num_) {}
这样,在main函数中这行代码
MyNum i = 10;
必须显式地调用构造函数
MyNum i(10);
因为它们可能导致意外的行为,尤其是在涉及用户定义的转换时,所以有时候会用explicit
关键字来禁止构造函数或类型转换运算符进行隐式转换