[Disclaimer: All Rights Reserved. You are welcome to reprint it. Do not use it for commercial purposes. Contact Email: feixiaoxing @ 163.com]
The default function is a basic feature of C ++. The default function definition is relatively simple. That is to say, if you do not have a specific value for one or more input parameters of a function, we will replace it with the default data. If you use your own data during the call process, the default data will be overwritten by our own data. The following is an example of a default function:
int add(int m, int n = 10){return m + n;}
What is the difference between calling and calling?
262: int p = add(2);00401488 push 0Ah0040148A push 20040148C call @ILT+15(add) (00401014)00401491 add esp,800401494 mov dword ptr [ebp-4],eax263: p = add(3, 4);00401497 push 400401499 push 30040149B call @ILT+15(add) (00401014)004014A0 add esp,8004014A3 mov dword ptr [ebp-4],eax
As shown in the code above, if a single data 2 is input, the compiler will help us input 10 by default. If the input data is 3 or 4, then the compiler replaces the default data 10 with 4. Therefore, the compiler helps us with intermediate replacement and judgment. So let's go back to the default template type we discussed today. What will happen? We can compile an example:
template <typename type1, typename type2 = int>class data{type2 value;public:data(type2 m): value(m) {}~data() {}};
We can see that the default type int is used in the second parameter. How can we prove that the default type can be used? We designed the following test case:
239: data<int, int> m(2);004013BD push 2004013BF lea ecx,[ebp-10h]004013C2 call @ILT+5(data<int,int>::data<int,int>) (0040100a)004013C7 mov dword ptr [ebp-4],0240: data<int> n(3);004013CE push 3004013D0 lea ecx,[ebp-14h]004013D3 call @ILT+5(data<int,int>::data<int,int>) (0040100a)
The code above defines two temporary variables, the first of which is m, the input type is int, the second temporary variable is N, and the input type is int and Int. As we mentioned above, the default type is int, so the constructor address of the first temporary variable M and the second Temporary Variable N should be the same. In fact, are the constructors of the two the same? We can view the function addresses of the two and find that one is 0x0040100a, and the other is 0x0040100a. The example proves that our judgment is correct.
After understanding the default template structure above, let's talk about the special template. What does a special template mean? It is not complicated. Since the template class is a general template, the data type can be any data type, but some data types (such as pointers) are inevitable ), we need to make some minor changes to some of these operations, but these small changes cannot be made in the original template definition. So what should we do? We have to redefine a form, which is the same as the template class definition name, but the form is slightly different. We can write a test to see:
template <typename type>class data{public:data() {printf("normal!\n");}~data() {printf("~normal!\n");}};template <>class data<int*>{public:data() {printf("point!\n");}~data() {printf("point!\n");}};
The above Code defines two class templates. However, the names of the two classes are the same, indicating that the content of these two classes is actually very similar. The first definition is the definition of the standard template class. The second is slightly more complex. The default int * is used. Because no specific type is used, the content after the template is empty. So how can we determine that both classes can be used normally? Let's take a look at the following example:
249: data<int> p;004013BD lea ecx,[ebp-10h]004013C0 call @ILT+45(data<int>::data<int>) (00401032)004013C5 mov dword ptr [ebp-4],0250: data<int*> q;004013CC lea ecx,[ebp-14h]004013CF call @ILT+35(data<int *>::data<int *>) (00401028)251: }
We found that the call address of the first function is 0x00401032, and the second address is 0x00401028. However, this cannot be explained, because the second address may also be extended by the first template class. We should follow each function (in fact, the address here is a jump address under VC ).
The actual entry function of the first variable is as follows:
234: data() {printf("normal!\n");}00401340 push ebp00401341 mov ebp,esp00401343 sub esp,44h00401346 push ebx00401347 push esi00401348 push edi00401349 push ecx0040134A lea edi,[ebp-44h]0040134D mov ecx,11h00401352 mov eax,0CCCCCCCCh00401357 rep stos dword ptr [edi]00401359 pop ecx0040135A mov dword ptr [ebp-4],ecx0040135D push offset string "normal!\n" (0042607c)00401362 call printf (00401540)00401367 add esp,40040136A mov eax,dword ptr [ebp-4]0040136D pop edi0040136E pop esi0040136F pop ebx00401370 add esp,44h00401373 cmp ebp,esp00401375 call __chkesp (004023b0)0040137A mov esp,ebp0040137C pop ebp0040137D ret
The second variable also needs to be followed by the input function:
242: data() {printf("point!\n");}00401430 push ebp00401431 mov ebp,esp00401433 sub esp,44h00401436 push ebx00401437 push esi00401438 push edi00401439 push ecx0040143A lea edi,[ebp-44h]0040143D mov ecx,11h00401442 mov eax,0CCCCCCCCh00401447 rep stos dword ptr [edi]00401449 pop ecx0040144A mov dword ptr [ebp-4],ecx0040144D push offset string "point!\n" (00426074)00401452 call printf (00401540)00401457 add esp,40040145A mov eax,dword ptr [ebp-4]0040145D pop edi0040145E pop esi0040145F pop ebx00401460 add esp,44h00401463 cmp ebp,esp00401465 call __chkesp (004023b0)0040146A mov esp,ebp0040146C pop ebp0040146D ret
When we see the above functions, we should understand that the constructors called by both are not the same. Therefore, special templates are usually prepared for those special data types. In this way, we have no concerns when using templates, and we can ignore the differences in the processing of various data types. Of course, because of the special model data, the special template makes our code more complete and more robust. We recommend that you use it more when designing the template.
Questions:
(1) Can the first type of the template class be default? Why do you think so?
(2) Can the following code be compiled on both VC 6.0 and VC 2005? Why? What do we think about designing code? (We recommend that you consider compatibility)
template <typename type>class data{public:data() {printf("normal!\n");}~data() {printf("~normal!\n");}};template <typename type>class data <type*>{public:data() {printf("point!\n");}~data() {printf("point!\n");}};
[Notice: The following two blogs are very interesting. We will introduce recursive templates and templates]