In this tutorial, we will explore the explicit keyword in C++ along with an illustrative example.
The explicit keyword in C++ is employed with constructors to prohibit implicit conversions. An explicit constructor in C++ is designated to prevent type conversions from occurring implicitly. This is crucial as implicit conversions can often lead to unforeseen outcomes. When a class has a constructor with only one parameter, that constructor will convert the single argument into the class created, essentially turning it into a conversion constructor. By utilizing the explicit keyword in C++, we can steer clear of these implicit conversions.
Working of C++ Explicit:
Firstly, constructors in C++ are defined as distinct methods that are automatically called upon the creation of a class object. These constructors play a crucial role in initializing the data members of the newly created object.
Now, let's delve into implicit type conversions and explore how to prevent them by leveraging the explicit keyword in C++. Implicit conversions happen automatically without direct instructions to the compiler. The process of converting one data type to another is known as casting. By using the explicit keyword in C++, we can avoid the compiler automatically executing the conversion, thus eliminating the need for manual casting.
We instruct the compiler to refrain from performing any implicit conversions on a constructor by explicitly specifying the keyword beforehand. Rather than allowing the compiler to carry out unwanted type conversions, we prefer to have those constructions explicitly called.
Examples:
Explicit constructors in C++ are defined to prevent implicit type conversions. When a constructor is marked as explicit, the compiler is restricted from performing any implicit conversions during object initialization with that constructor. Below are various C++ illustrations showcasing the usage of explicit constructors:
Example:
#include <iostream>
class MyNumber {
public:
explicit MyNumber(int value) : number(value) {}
int getValue() const {
return number;
}
private:
int number;
};
int main() {
// Using an explicit constructor requires explicit type conversion
MyNumber number1(72); // OK, direct initialization
MyNumber number2 = MyNumber(85); // OK, explicit constructor called
// Uncommenting the following lines will result in a compilation error
// MyNumber num3 = 55; // Error, implicit conversion not allowed
// MyNumber num4 = 3.14; // Error, implicit conversion not allowed
std::cout << "number1: " << number1.getValue() << std::endl;
std::cout << "number2: " << number2.getValue() << std::endl;
return 0;
}
Output:
number1: 72
number2: 85
Explanation:
- In this example, the code defines a class named MyNumber , which encapsulates an integer value (number) and provides an explicit constructor to initialize it.
- The constructor explicit MyNumber(int value) is declared explicit, meaning it cannot be used for implicit type conversions. It requires an explicit type conversion when constructing MyNumber
- In the main function:
- MyNumber number1(72); This line directly initializes number1 with an integer value of 72. It is allowed because it's direct initialization.
- MyNumber number2 = MyNumber(85); It explicitly calls the constructor with the argument 85 and initializes number2 with the result. It is also allowed due to the explicit constructor call.
- The lines MyNumber num3 = 55; and MyNumber num4 = 3.14; These lines are commented out because they would result in compilation errors. These lines attempt to perform implicit type conversions, which are not allowed because the constructor is declared explicit. We would need to use explicit type conversion to fix these errors, such as MyNumber num3(staticcast<int>(55)); or MyNumber num4(staticcast<int>(3.14));.
- Finally, the code prints the values stored in number1 and number2 to the console using std::cout
- Preventing Implicit Conversions: When a constructor is designated as explicit, it prevents its parameter from being automatically or implicitly converted to the class type. It helps in the prevention of accidental and potentially error-prone type conversions.
- Strict Requirements for Constructors: We can develop constructors that impose specific criteria or constraints on their parameters. Declaring the constructor explicitly requires users to specify the right type, demonstrating that they know the requirements.
- Avoiding Ambiguity: In events when numerous constructors could be used for initialization, the explicitly specified keyword can resolve ambiguity. It helps the compiler select the appropriate constructor based on the arguments provided.
- Preventing Unintended Object Creation: A class may have a method called a constructor that accepts a single argument, and we wish to prevent instances from being created by accident using this construction.