C++ Basics: The explicit Keyword

1. What is explicit?

  • explicit is a C++ keyword
  • It modifies constructors and type conversion functions
  • Purpose: to prohibit implicit type conversions

2. What is the use of explicit?First, let’s look at the following example:

class A{public:  A(int x) { }};
void foo(A a) { }
foo(10);  // Valid, int implicitly converts to A

By default, single-parameter constructors allow implicit conversions. However, this can lead to unexpected behavior. As shown below, the constructor of B does not have explicit, so 10 can be implicitly converted to B; the constructor of A has explicit, so 10 cannot be converted to a variable of class A.C++ Basics: The explicit KeywordOnly explicit construction can be used: A a(10)3. Usage scenariosTo avoid potential bugs, single-parameter constructors should generally be marked as explicit; type conversion constructors and single-parameter constructors with default parameters are also recommended to be marked as such; multi-parameter constructors do not require explicit as they cannot perform implicit type conversions.Type conversion constructors are single-parameter non-explicit constructors used to implicitly construct the current class object from other types.

class MyString {public:    explicit MyString(const char* s);  // Type conversion constructor};
void print(const MyString& str);
int main() {    print("hello");  // Valid: const char* is implicitly converted to MyString}

In this example,<span>MyString(const char* s)</span> is a type conversion constructor that allows the compiler to automatically convert <span>const char*</span> to <span>MyString</span> type.Single-parameter constructors with default parameters refer to constructors that have only one parameter without a default value, while the remaining parameters (if any) have default values, allowing only one argument to be passed during the call.

class MyClass {public:    explicit MyClass(int x, double y = 3.14);  // Single-parameter constructor with default parameters};
int main() {    MyClass obj(10);  // Only passing one parameter, valid}

4. Other effects of explicitSince C++11, it supports modifying type conversion functions.

class People{public:    explicit operator bool() const{ return true; }}
People p;if(p) { ...}   // Valid
int x=p;    // Implicit conversion to int is not allowed

5. Interview extension questions + answer examplesQ1: What is the effect of adding explicit to the default constructor?Answer: It means prohibiting implicit initialization like T obj={};, and must use explicit methods like T obj{}; or T obj();. This can prevent misinitialization in certain frameworks, but generally, it is not recommended to add explicit to default constructors unless there are special restrictions.Q2: Why do almost all constructors in STL containers have explicit?Answer: Because STL containers have single-parameter constructors, if explicit is not added, implicit type conversions can easily occur during assignment and initialization, potentially leading to logical errors. Adding explicit forces developers to use explicit initialization for containers, enhancing safety and readability.Q3: What is the effect of using explicit and delete together?Answer: Both can be used together to restrict specific construction methods, for example, you can delete a certain implicit conversion type and then add explicit to another constructor, thus controlling the object construction rules more precisely.

class myStr{public:    myStr(const char *s)=delete;    // Prohibit conversion, explicit conversion is also not allowed    explicit myStr(string s){}       // Prohibit implicit conversion};

6. Recommended interview answer template (30 seconds)explicit is to prevent implicit type conversions from single-parameter constructors, which can easily cause logical errors. It requires explicit calls to constructors or conversion functions. It is particularly suitable for resource classes, container classes, string wrappers, etc., to prevent strange automatic conversion behaviors.7. SummaryThe explicit keyword prevents implicit type conversions, avoiding potential bugs, and serves as a shield for constructors.

Leave a Comment