Ключевое слово explicit используется в C++ для предотвращения неявных преобразований при вызове конструктора. Оно применяется к конструкторам, чтобы указать компилятору, что этот конструктор должен быть вызван явно, а не через неявное преобразование типов.
Проблема неявного преобразования
Когда конструктор не является explicit, он может использоваться для неявного преобразования типов, что иногда приводит к нежелательным или непредсказуемым результатам.
Пример без использования explicit
#include <iostream>
class MyClass {
public:
MyClass(int x) {
std::cout << "Constructor called with value: " << x << std::endl;
}
};
void printMyClass(const MyClass& obj) {
std::cout << "Function called" << std::endl;
}
int main() {
MyClass obj = 10; // Неявный вызов конструктора
printMyClass(20); // Неявное преобразование int в MyClass
return 0;
}Пример с использованием explicit
#include <iostream>
class MyClass {
public:
explicit MyClass(int x) {
std::cout << "Constructor called with value: " << x << std::endl;
}
};
void printMyClass(const MyClass& obj) {
std::cout << "Function called" << std::endl;
}
int main() {
MyClass obj(10); // Явный вызов конструктора
printMyClass(MyClass(20)); // Явное преобразование int в MyClass
// printMyClass(20); // Ошибка: неявное преобразование запрещено
return 0;
}Пояснение
-
Без
explicit:- Конструктор
MyClass(int x)может быть вызван неявно. - Вызов
MyClass obj = 10;работает, так как неявно вызывается конструктор. - Вызов
printMyClass(20);также работает, так как20неявно преобразуется в объектMyClass.
- Конструктор
-
С
explicit:- Конструктор
MyClass(int x)должен быть вызван явно. - Вызов
MyClass obj(10);работает, так как конструктор вызывается явно. - Вызов
printMyClass(MyClass(20));работает, так как преобразование выполняется явно. - Вызов
printMyClass(20);приводит к ошибке, так как неявное преобразование запрещено.
- Конструктор