First, the explicit keyword in C++ can only be used to modify a class constructor with only one parameter. Its function is to show that the constructor is displayed, not implicit. The other key corresponding to it is implicit, meaning hidden. Class constructors are declared implicit by default.
So what's the difference between a constructor that displays a declaration and an implicit declaration? Let's look at the following example:
- class CxString //Class declarations that do not use the explicit keyword are implicit declarations by default
- {
- public:
- char *_pstr;
- int _size;
- CxString(int size)
- {
- _size = size; //Preset size of string
- _pstr = malloc(size + 1); //Allocate string memory
- memset(_pstr, 0, size + 1);
- }
- CxString(const char *p)
- {
- int size = strlen(p);
- _pstr = malloc(size + 1); //Allocate string memory
- strcpy(_pstr, p); //Copy strings
- _size = strlen(_pstr);
- }
- //Destructors are not discussed here.
- };
- //The following is the call:
- CxString string1(24); //This is OK, which pre-allocates 24 bytes of memory for CxString
- CxString string2 = 10; //This is OK, which pre-allocates 10 bytes of memory for CxString
- CxString string3; //This is not possible because there is no default constructor and the error is "CxString": no appropriate default constructor is available
- CxString string4("aaaa"); //This is OK's
- CxString string5 = "bbb"; //This is also OK, calling CxString(const char * p)
- CxString string6 = 'c'; //This is OK. In fact, it calls CxString(int size) and size equals ascii code of'c'.
- string1 = 2; //This is also OK, which pre-allocates 2 bytes of memory for CxString
- string2 = 3; //This is also OK, which pre-allocates 3 bytes of memory for CxString
- string3 = string1; //This is OK, at least compilation is fine, but if you use free release_pstr memory pointer in the destructor, you may get an error. The complete code must overload the operator "=" and handle memory release in it.
In the above code, "CxString string 2 = 10;" Why is it possible? In C++, if the constructor has only one parameter, then there will be a default conversion operation at compile time: the data corresponding to the data type of the constructor will be converted to this kind of object. That is to say, "CxString string 2 = 10;" This code, the compiler automatically converts the integer to CxS. The tring class object is actually equivalent to the following operations:
- CxString string2(10);
- or
- CxString temp(10);
- CxString string2 = temp;
However, the _size in the above code represents the size of the string memory allocation, so the second sentence of the call "CxString string 2 = 10;" and the sixth sentence "CxString string 6 = c';" seem incoherent and confusing. What can prevent this use? The answer is to use the explicit keyword. Let's modify the above code as follows:
- class CxString //Use the keyword explicit class declaration to display the transformation
- {
- public:
- char *_pstr;
- int _size;
- explicit CxString(int size)
- {
- _size = size;
- //Ibid., omit...
- }
- CxString(const char *p)
- {
- //Ibid., omit...
- }
- };
- //The following is the call:
- CxString string1(24); //This is OK's
- CxString string2 = 10; //This is not possible because the explicit keyword cancels the implicit conversion
- CxString string3; //This is not possible because there is no default constructor
- CxString string4("aaaa"); //This is OK's
- CxString string5 = "bbb"; //This is also OK, calling CxString(const char * p)
- CxString string6 = 'c'; //This is not possible. In fact, CxString(int size) is called, and size equals ascii code of'c', but the explicit keyword cancels the implicit conversion.
- string1 = 2; //This is also not possible because implicit conversions have been abolished
- string2 = 3; //This is also not possible because implicit conversions have been abolished
- string3 = string1; //This is also not possible because implicit conversions are cancelled unless the class implements the overload of the operator "="
The function of the explicit keyword is to prevent the implicit automatic conversion of class constructors.
As mentioned above, the explicit keyword is only valid for a class constructor with one parameter. If the class constructor parameter is greater than or equal to two, there will be no implicit conversion, so the explicit keyword is invalid. For example:
- class CxString //explicit keywords are invalid when class constructor parameters are greater than or equal to two
- {
- public:
- char *_pstr;
- int _age;
- int _size;
- explicit CxString(int age, int size)
- {
- _age = age;
- _size = size;
- //Ibid., omit...
- }
- CxString(const char *p)
- {
- //Ibid., omit...
- }
- };
- //Whether there is an explicit keyword or not is the same at this time.
However, there is an exception, that is, the explicit keyword is still valid when all parameters except the first parameter have default values. At this time, when the constructor is called, only one parameter is passed in, which is equivalent to a class constructor with only one parameter. The example is as follows:
- class CxString //Use the keyword explicit declaration
- {
- public:
- int _age;
- int _size;
- explicit CxString(int age, int size = 0)
- {
- _age = age;
- _size = size;
- //Ibid., omit...
- }
- CxString(const char *p)
- {
- //Ibid., omit...
- }
- };
- //The following is the call:
- CxString string1(24); //This is OK's
- CxString string2 = 10; //This is not possible because the explicit keyword cancels the implicit conversion
- CxString string3; //This is not possible because there is no default constructor
- string1 = 2; //This is also not possible because implicit conversions have been abolished
- string2 = 3; //This is also not possible because implicit conversions have been abolished
- string3 = string1; //This is also not possible because implicit conversions are cancelled unless the class implements the overload of the operator "="
The above is a detailed description of the C++ explicit keyword.