First Let us look at below code for understanding explicit keyword in c++

// A class
class A {};

// Another simple class B
class B
{
public:
   B() {}
   B(A const&) {}
};

void f(B const&) {}

int main()
{
   A obj;
   f(obj); // Spot the deliberate mistake
}

In above example A and B class is unrelated class. the function f( B const&) expects a B. But in main() we have passed unrelated object obj of class Type A.

What will compiler do in this situation?

C++ compiler will silently construct a temporary instance of class B like

int main()
{
   A obj;
  {
    B obj_arg0(obj);
    f(obj_arg0);
   }
}

Constructor of class B can be used to convert the parameter to the correct type.The compiler is allowed to do this once for each parameter.

Problem Situation:
Above example, the effect of this conversion is ignored, however consider the case where the construction of B from A requires a lengthy conversion process, or (worse) the case where the function f stores some data from its argument. This should be entirely legal since the argument is passed by reference, but since the compiler decided to construct a temporary, the argument goes out of scope after the function has been called, invalidating the stored data. This sort of situation can lead to nightmarish bugs, since no compiler warnings will ever be generated from the conversion.
(reference taken from blog http://www.sjbrown.co.uk/2004/05/01/always-use-explicit/)

Prefixing the explicit keyword to the constructor prevents the compiler from using that constructor for implicit conversions. Adding it to the above class will create a compiler error at the function call f (obj).

Another example:
Suppose you have a class String

class String {
public:
String(int n); // allocate n bytes to the String object
String(const char *p); // initializes object with char *p
}

Now if you try
String mystring = ‘x’;

the char ‘x’ will be converted to int and will call String(int) constructor. But this is not what the user might have intended. So to prevent such conditions, we can define the class’s constructor as explicit.

class String {
public:
explicit String (int n); //allocate n bytes
String(const char *p); // initialize sobject with string p
}


Related Contents to follow