Ключевое слово 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;
}

Пояснение

  1. Без explicit:

    • Конструктор MyClass(int x) может быть вызван неявно.
    • Вызов MyClass obj = 10; работает, так как неявно вызывается конструктор.
    • Вызов printMyClass(20); также работает, так как 20 неявно преобразуется в объект MyClass.
  2. С explicit:

    • Конструктор MyClass(int x) должен быть вызван явно.
    • Вызов MyClass obj(10); работает, так как конструктор вызывается явно.
    • Вызов printMyClass(MyClass(20)); работает, так как преобразование выполняется явно.
    • Вызов printMyClass(20); приводит к ошибке, так как неявное преобразование запрещено.