A constructor taking a single argument is by default an implicit conversion operator:
class C { int I; //... public: C(int i);//constructor and implicit conversion operator //as well }; void f() { C c(0);c = 5; //implicit conversion of 5 to a C object and //then assignment }
The compiler re-edits the above sample as if the programmer had written:
////////////////////////////////////////////////////////////////////////////////////////// //"c=5;" transformed by the compiler into something like this: ///////////////////////////////////////////////////////////////////////////////////////// C temp(5);//temporary object instantiated, c = temp; //assigned using operator = temp.C::~C(); //temp's destructor activated
In many cases, this conversion is intentional and well-behaved. But there are cases where such automatic conversion is undesirable, like the following:
class String { int size; char *p; //.. public:String (int sz); //constructor & implicit conversion //operator; undesirable in this case }; void f () { String s(10); //the following is a programmer's typo; yet it is not //detected since it has an unexpected interpretation: s = 100; //bad; 100 is converted to a String and then //assigned to s. }
In order to avoid such implicit conversions, a constructor taking one argument should be declared as explicit:
class String { int size; char *p; //.. public: //no implicit conversion explicit String (int sz); //no implicit conversion String (const char *s, int size n = 0); //implicit conv. };void f () { String s(10);s = 100; //now compile time error; explicit conversion //required now:s = String(100); //fine; explicit conversions = "st";//fine; implicit conversion allowed in this case }