参见:【028】深入理解C++ 类和对象:构造、析构、拷贝构造、初始化列表 详解(最全讲解)_c++类构造初始化-CSDN博客
C++提供了关键字explicit
禁止通过构造函数进行的隐式转换;声明为explicit
的构造函数不能在隐式转换中使用。
explicit
用于修饰构造函数构造函数,防止隐式转换;是针对单参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参数构造)而言的。
一、不使用 explicit
的情况(允许隐式转换)
#include <iostream>
class Example {
public:
// 单参数构造函数(未使用 explicit)
Example(int x) {
value = x;
std::cout << "Constructor called with value: " << value << std::endl;
}
int getValue() const {
return value;
}
private:
int value;
};
void displayExample(const Example &ex) {
std::cout << "Value is: " << ex.getValue() << std::endl;
}
int main() {
Example ex1 = 100; // 隐式转换,调用 Example(int x) 构造函数
displayExample(200); // 隐式转换,调用 Example(int x) 构造函数
return 0;
}
Constructor called with value: 100
Constructor called with value: 200
Value is: 200
二、使用 explicit
的情况(禁止隐式转换)
#include <iostream>
class Example {
public:
// 单参数构造函数(使用 explicit)
explicit Example(int x) {
value = x;
std::cout << "Constructor called with value: " << value << std::endl;
}
int getValue() const {
return value;
}
private:
int value;
};
void displayExample(const Example &ex) {
std::cout << "Value is: " << ex.getValue() << std::endl;
}
int main() {
Example ex1(100); // 直接调用构造函数,可以成功
displayExample(ex1); // 直接传递对象,可以成功
// Example ex2 = 200; // 错误! 隐式转换被禁止
// displayExample(300); // 错误! 隐式转换被禁止
return 0;
}
Constructor called with value: 100
Value is: 100
三、解释
-
不使用
explicit
的例子:- 单参数构造函数
Example(int x)
可以被隐式调用。 - 在
main
中Example ex1 = 100;
和displayExample(200);
都是隐式的,将int
自动转换为Example
对象。
- 单参数构造函数
-
使用
explicit
的例子:- 在定义构造函数时使用
explicit
关键字:explicit Example(int x) { ... }
- 在
main
中,必须使用直接的方式来调用构造函数和传递参数,不允许隐式转换。例如:Example ex1(100); // 显式调用 displayExample(ex1); // 直接传递对象
- 注释掉的代码会导致编译错误,因为
explicit
构造函数禁止隐式转换:Example ex2 = 200; // 错误! 隐式转换被禁止 displayExample(300); // 错误! 隐式转换被禁止
- 在定义构造函数时使用