Original: http://www.cnblogs.com/visayafan/archive/2011/11/27/2265349.html
Turn http://blog.csdn.net/callmeback/article/details/4039304
Not translated, relatively simple.
This is Ansi/iso C + + Professional Programmer ' s handbook.
Explicit constructors
A constructor that takes a single argument are, by default, an implicit conversion operator, which converts their argument to
An object of its class (see also Chapter 3, "Operator overloading"). Examine the following concrete example:
Class String{private: int size; int capacity; Char *buff;public: string (); string (int size); constructor and implicit conversion operator string (const char *);//constructor and implicit conversion operator< C6/>~string ();};
Class string has three constructors:a the default constructor, a constructor that takes int, and a constructor that
Constructs a string from const char *. The second constructor is used to create a empty string object with an
Initial preallocated buffer at the specified size. However, in the case of class string, the automatic conversion is
Dubious. converting an int to a string object doesn ' t make sense, although this was exactly what this constructor does.
Consider the following:
int main () { string s = "Hello";//ok, convert a c-string into a string object int ns = 0; s = 1; 1 oops, programmer intended to write NS = 1,}
In the expression s= 1, the programmer simply mistyped the name of the variable ns, typing s instead. Normally,
The compiler detects the incompatible types and issues an error message. However, before ruling it out, the compiler first
Searches for a user-defined conversion that allows this expression; Indeed, it finds the constructor that takes int.
Consequently, the compiler interprets the expression s= 1; As if the programmer had written
s = string (1);
Might encounter a similar problem when calling a function that takes a string argument. The following example
Can either be a cryptic coding style or simply a programmer ' s typographical error. However, due to the implicit
Conversion constructor of class string, it'll pass unnoticed:
int f (string s); int main () { f (1);//Without a explicit constructor,//this call is expanded Into:f (string (1)); /was that intentional or merely a programmer ' s typo?}
' In order to avoid such implicit conversions, a constructor that takes one argument needs to be declared explicit:
Class String{//...public: explicit string (int size),//block implicit conversion string (const char *); Implicit conversion ~string ();};
An explicit constructor does not behave as a implicit conversion operator, which enables the compiler to catch the
Typographical error this time:
int main () { string s = "Hello";//ok, convert a c-string into a string object int ns = 0; s = 1; Compile time error; This time the compiler catches the typo}
Why aren ' t all constructors automatically declared explicit? Under some conditions, the automatic type conversion is
Useful and well behaved. A Good example of the third constructor of string:
string (const char *);
The implicit type conversion of const char * to a String object enables it users to write the following:
string S;
s = "Hello";
The compiler implicitly transforms this to
string S;
Pseudo C + + code:
s = string ("Hello"); Create a temporary and assign it to s
On the other hand, if you are declare this constructor explicit, you have to use explicit type conversion:
Class String{//...public: explicit string (const char *);}; int main () { string s; s = string ("Hello"); Explicit conversion now required return 0;}
Extensive amounts of legacy C + + code rely on the implicit conversion of constructors. The C + + standardization
Committee was aware of that. In order to do existing code break, the implicit conversion is retained. However, a
New keyword, explicit, was introduced to the Languageto enable the programmer to block the implicit conversion
When it was undesirable. As a rule, a constructor that can is invoked with a single argument needs to be declared
Explicit. When the implicit type conversion are intentional and well behaved, the constructor can being used as an
implicit conversion operator.
Add
The role of explicit keywords in C + +
In C + +, if a class has a constructor that has only one parameter, C + + allows a special way to declare class variables. In this case, you can directly assign a data that corresponds to a constructor parameter type directly to a class variable, and the compiler automatically casts the type at compile time, converting the data corresponding to the constructor parameter type to the object of the class. If you precede the constructor with the explicit modifier, this automatic conversion is prohibited, in which case the compiler will give an error even if the data corresponding to the constructor parameter type is directly assigned to the class variable.
The following is a specific example to illustrate.
Create a People.cpp file, and then enter the following:
class people
{
Public
int age;
Explicit people (int a)
{
Age=a;
}
};
void foo (void)
{
People P1 (10); Way One
people* p_p2=new people (10); Way Two
People p3=10; Mode three
}
This C + + program defines a class people that contains a constructor that contains only an integer parameter A that can be used to initialize the age variable when the class is constructed.
Then we defined a function foo, in which we created three 10-year-old "people" in three different ways. The first is the most general way of declaring a class variable. The second way is to declare a pointer variable of the People class, and then dynamically create a people instance in the heap and assign the address of the instance to P_P2. The third way is what we call the special way, why say special? As we all know, C + + is a strong type language, different data types are not arbitrary conversion, if you want to do type conversion, you must make explicit coercion type conversion, and here, there is no explicit conversion, directly assign an integer data to the class variable P3.
Therefore, it can be said that there is an implicit type conversion, the compiler automatically converts the data corresponding to the constructor parameter type in order to the object of the class, so that the way the compiler automatically converted and the way a final implementation is the same.
Don't believe it? Listen to the false, seeing is real, let us look at the bottom of the implementation of the way.
In order to make it easier to compare the implementation of mode one and mode three, we make a little change to the above code, removing the way two:
void foo (void)
{
People P1 (10); Way One
People p3=10; Mode three
}
The reason for the removal is that the second way is to create the class instance dynamically on the heap, so there will be some additional code impact analysis. After the modification is complete, compile people.cpp with the following command
$ gcc-s People.cpp
The "-S" option is the GCC output assembler code. After the command executes, the PEOPLE.S is generated by default. The key elements are as follows:
. Globl _z3foov
. Type _z3foov, @function
_z3foov:
. LFB5:
PUSHL%EBP
. LCFI2:
MOVL%esp,%EBP
. LCFI3:
Subl $24,%esp
. LCFI4:
MOVL, 4 (%ESP)
Leal-4 (%EBP),%eax
Movl%eax, (%ESP)
Call _zn6peoplec1ei
MOVL, 4 (%ESP)
Leal-8 (%EBP),%eax
Movl%eax, (%ESP)
Call _zn6peoplec1ei
Leave
Ret
See ". LCFI4 "The thing behind the line, 1-4 lines and 5-8 lines almost exactly the same, 1-4 lines is the assembly code of Mode one, 5-8 is the assembly code of mode three. Careful you may find that 2 and 6 lines are different, one is -4 (%EBP) and the other one is -8 (%EBP), which is the address of the class variable P1 and P3 respectively.
This can be said to be a feature of C + + for strongly typed languages that do not arbitrarily perform type conversions. Oh, today seems to be not about C + + features, but to know the role of the explicit keyword?
What is the role of the explicit keyword? Its role is to prohibit this feature. As at the beginning of the article, any constructor that is modified with the explicit keyword will not be converted automatically at compile time, and an error is made.
Let's see it! To modify the code:
class people
{
Public
int age;
Explicit people (int a)
{
Age=a;
}
};
And then compile:
$ gcc-s People.cpp
The compiler immediately error:
people.cpp:In function ' void foo () ':
PEOPLE.CPP:23: Error: Request to convert from ' int ' to non-scalar type ' people '
A second reprint
Explicit meaning is obvious, and it corresponds to a word is implicit meaning is hidden.
I refer to the description of this keyword in MSDN and the C + + standard library, and refer to the explanation of this keyword on the web. It is now used and summarized in the following records:
First, this keyword can only be used in class constructors . Its role is that it cannot be implicitly converted.
Class Gxgexplicit//classes with no keyword explicit
{
Public
int _size;
gxgexplicit (int size)
{
_size = size;
}
};
Here is the call
Gxgexplicit gE1 (24); This is no problem.
Gxgexplicit gE2 = 1; It's not a problem.
Gxgexplicit gE3; This is not possible, there is no default constructor
GE1 = 2; It's not a problem.
gE2 = 3; It's not a problem.
gE2 = gE1; It's not a problem.
But if Gxgexplicit is modified to stack, our _size represents the size of the stack, then the second sentence of the call is nondescript, and easy to confuse. This is not a form that allows code readers to understand and accept, although it is legal (compilers can compile). This is because the compiler has implicit conversion functionality by default, and you enter gE2 = 1 to compile the same result as the first sentence. So, explicit comes in handy. Modify the code to:
Class Gxgexplicit
{
Public
int _size;
explicit gxgexplicit (int size)
{
_size = size;
}
};
Continue with the above call:
Gxgexplicit gE1 (24); This is no problem.
Gxgexplicit gE2 = 1; This doesn't work, the keyword cancels the implicit conversion
Gxgexplicit gE3; This is not possible, there is no default constructor
GE1 = 2; This doesn't work, the keyword cancels the implicit conversion
gE2 = 3; This doesn't work, the keyword cancels the implicit conversion
gE2 = gE1; This is not possible, the keyword cancels the implicit conversion unless the class implements an overload of the operator "=".
This is the compiler (VS2005) display: cannot convert from ' int ' to ' gxgexplicit '.
It is also seen from here that the function of the keyword is to mask the compiler's implicit conversion.
A note on MSDN describes the fact that an implicit conversion is automatically canceled when the constructor parameter exceeds two. For example
Class Gxgexplicit
{
Private
int _size;
int _age;
Public
Explicit gxgexplicit (int age, int size)
{
_age = age;
_size = size;
}
};
This is no keyword effect is the same. That's the equivalent of having this keyword.
But there is another exception: there is only one parameter that must be entered, and the rest is a parameter with a default value.
Class Gxgexplicit
{
Private
int _size;
int _age;
Public
Explicit gxgexplicit (int age, int size = 0)
{
_age = age;
_size = size;
}
};
Class Gxgexplicit
{
Private
int _size;
int _age;
int _hight;
Public
Explicit gxgexplicit (int age, int size = 0)
{
_age = age;
_size = size;
_hight = hight;
}
};
IMPLICIT/EXPLICIT conversion (reprint)