I love thinking in series, so I started this name. The idea of this article is also part of this set of books, for example, comparison, or in-depth mining, or to make up for wisdom, or to make sense, including thinking in C ++, it even includes thinking in Java.
Thinking again in C ++ (3) misunderstandings of default parameters
Keywords: C ++, default parameter, default argument, function, function, constructor, misunderstanding
Avoid the following mistakes when using the default parameters.
1. Misuse of default parameters damages the structure and readability of the Code.
Void F (bool B = false)
{
If (B)
{
File: // code of Open File
}
Else
{
File: // code of close file
}
}
Opening and closing a file have nothing in common in implementation code. Two functions belonging to the same category are mistaken for the same implementation mechanism, and a parameter is fabricated out of thin air to combine them together, no benefit! On the contrary, who can remember that F (true) indicates opening, and F () indicates closing? Moreover, both F (false) and F () can close files. If the caller uses them together, the maintenance becomes more difficult. In this case, it is very clear to write two independent functions.
Void open ()
{
File: // code of Open File
}
Void close ()
{
File: // code of close file
}
By extension, the following practices are also debatable.
Class cstring
{
PRIVATE:
Char * pcdata;
Public:
Cstring (char * Pc = NULL );
};
Cstring: cstring (char * PC)
{
If (Pc = NULL)
{
Pcdata = new char [1];
//...
}
Else
{
Pcdata = new char [strlen (PC) + 1];
//...
}
}
This one is even more confusing. "They are all constructors. Of course they are written in one piece ." Someone said. None! It should be seen that the no-argument constructor is completely separated from the code used by the constructor with the char * parameter, and the default parameter value null does not play any role in setting data members. The cstring () constructor should be rewritten as follows:
Class cstring
{
PRIVATE:
Char * pcdata;
Public:
Cstring ();
Cstring (char * PC );
};
Cstring: cstring ()
{
Pcdata = new char [1];
//...
}
Cstring: cstring (char * PC)
{
Pcdata = new char [strlen (PC) + 1];
//...
}
Summary:
(1) Any case where the default parameter value is used for if judgment and the code is completely different after judgment should be split into two independent functions.
(2) it is reasonable only when the default parameter value is not discriminated against in the function body, that is, the function's implementation mechanism for any parameter is the same.
2. Multiple default parameters may introduce a logically ambiguous call method.
Designing a class not only provides the correct functions to the customer's code, but also limits the incorrect usage.
Class cpoint
{
Public:
Int X;
Int y;
Cpoint (INT x = 0, int y = 0)
{
This-> X = X;
This-> Y = y;
}
};
At first glance, there is no problem. If you do not specify the initial values of X and Y when constructing a cpoint object, it is set to the origin coordinate. Let's test:
Cpoint pnt1;
Cpoint pnt2 (100,100 );
Cpoint pnt3 (100); file: // [1]
The result shows that the value of pnt3 is (, 0) and runs to the X axis. We can't do anything to bind two parameters so that they are both default or not default at the same time. However, if the default parameter is removed, the situation will improve.
Class cpoint
{
Public:
Int X;
Int y;
Cpoint ()
{
X = 0;
Y = 0;
}
Cpoint (int x, int y)
{
This-> X = X;
This-> Y = y;
}
};
In this way, the statement [1] will cause a compilation error and remind the user.
"Cpoint pnt3 (100); initialized to the X axis, this is what I wanted ." Really? So, please clearly specify this unique call method in your class document and tell the user that it is the form of cpoint pnt4 (0,100) to initialize the point to the Y axis.
As for me, self document is ready.
3. ambiguity may occur during heavy load
This is a simple example:
Void F (int A, int B = 0)
{
}
Void F (int)
{
}
Although the potentially ambiguous state is not an error, the latency may end when such code is generated.
4. Schizophrenia in function calls
The terms in Objective C ++ 2nd are added here for the integrity of this article. The rare symptom is that the derived class overrides the default parameter value of the base class virtual function.
Class cbase
{
Public:
Virtual void F (INT I = 0)
{
Cout <"in cbase" <I <Endl;
}
};
Class cderive: Public cbase
{
Public:
Virtual void F (INT I = 100)
{
Cout <"in cderive" <I <Endl;
}
};
Cderive D;
Cbase * pb = & D;
Pb-> F (); file: // [2]
Output after running:
In cderive 0
Remember, the default parameter is static binding, while the virtual function is dynamic binding. Therefore, [2] runs the function body of cderive: F, the default value is 0 of cbase.
Digress:
Why (2) the access volume is so low, only 1/3 of (1. I think (2) it is better than (1), but I don't have any comments. I'm sad ......
Thinking again in C ++ (2) the auto-assigned value is non-public disconnected.
Http://www.csdn.net/Develop/read_article.asp? Id = 16713
Thinking again in C ++ (I) Principle of constants
Http://www.csdn.net/Develop/read_article.asp? Id = 16554