Explicit is used to prevent implicit conversions defined by constructors.
To understand what it does, first understand the implicit conversion: a constructor that can be called with a single argument defines an implicit conversion from the formal parameter type to the class type.
For example:
Class Things
{
Public
Things (const std::string &name = ""):
M_name (name), height (0), weight (10) {}
int CompareTo (const things & other);
Std::string M_name;
int height;
int weight;
};
Here the things constructor can be initialized with just one argument. So you can do an implicit conversion, like this:
Things A;
....//is initialized and used here. \//here.
std::string nm = "Book_1";
Because you can implicitly convert, you can use the following
int result = A.compareto (nm);
This program uses a string type object as an argument to pass the CompareTo function to things. This function would have required a Tings object as an argument. Now the compiler uses string nm to construct and initialize a
The things object, the newly generated temporary things object, is passed to the CompareTo function and is refactored after leaving the function.
The correctness of this behavior depends on the business needs. If you just want to test the ratio of the weight of a to the size of 10, it might be convenient to do so. If, however, the CompareTo function involves dividing the height property to be initialized to 0, it might be wrong to do so. You need to change the height property to not 0 after you construct tings. So to limit this implicit type conversion.
It is then possible to prevent implicit type conversions by declaring the constructor as explicit.
The explicit keyword can only be used on a constructor declaration inside a class, not on a function definition outside the class. Now the things class looks like this:
Class Things
{
Public
Explicit things (const std::string &name = ""):
M_name (name), height (0), weight (0) {}
int CompareTo (const things & other);
Std::string M_name;
int height;
int weight;
};
When you compile, you will be prompted on vs2008: There is no user-defined conversion operator available to perform the transformation, or the operator cannot be called.
You can still use the constructor to complete the above type conversion by showing:
Things A;
....//is initialized and used here. \//here.
std::string nm = "Book_1";
Show using constructors
int result = A.compareto (Things (nm));
The advantage of Google's C + + specification for explicit is that it avoids outdated types of transformations, which have no drawbacks. So Google agreed that all single-parameter constructors must be displayed, and in rare cases the copy constructor can not declare explicit. For example, a class that is a transparent wrapper for other classes.
Effective C + + says: Constructors declared as explicit are generally more popular than their non-explicit brothers. Because they prohibit the compiler from performing type conversions that are not expected (and are often not expected). Unless I have a good reason to allow the constructor to be used for implicit type conversions, I will declare it as explicit. I encourage you to follow the same policy.
C + + Explicit keywords avoid implicit conversions