Terms 24: Careful choices between function overload and setting parameters
The reason for confusing the function overload and setting parameters defaults is that they all allow a function to be called in a variety of ways:
Void f (); // f is overloaded Void F (int x);
f (); // Call f () f (10); // call f (int)
Void g (int x = 0); // G has a // default parameter value
g (); // Call G (0) g (10); // Call G (10)
So, when should I use?
The answer depends on the other two questions. First, there is a value that can be used as a default? Second, how many algorithms do you want to use? In general, if a suitable default value can be selected and only one algorithm is used, the default parameter is used (see Terms 38). Otherwise, use the function overload.
Below is a function of up to the maximum maximum value of five int. This function is used - deep breath, see clearly --std :: numeric_limits
Int Max (int A, int b = std :: min (), int c = std :: numeric_limits
It can now be relaxed. std :: numeric_limits
Suppose wants to write a function template, its parameter is a fixed digital type, and the function generated by the template can print the minimum value represented by "Instantiated Type". This template can be written like this:
Template
If you just write this function with
In order to avoid these difficulties, standard C libraries (see clause 49) define a class template Numeric_Limits in header file
Template
Numeric_Limits based approach to "Type-related constants" seems to be overhead, which is not. Because the length of the original code is not reflected in the generated target code. In fact, no instructions are generated at all calls to Numeric_LIMITS. Want to know what is going on, look at the following, this is a very simple implementation of numeric_limits
#include
Namespace std {
INLINE INT NUMERIC_LIMITS
}
Because this function is declared as inline, it will be replaced by a function of its call (see Terms 33). It is just an int_min, that is, it is just a simple "constant defined constant". #Define. So even if the MAX function starting at this Territor seems to be called to each default parameter, it is only used to use another smart method to represent a type related constant (in this example INT_MIN). Some efficient and clever applications are all in C standard library, which can be referred to Terms 49.
Back to the MAX function: The most critical is that the MAX calculation is the same (very low) algorithm when the MAX calculation is calculated regardless of the number of parameters of the function. Which parameters don't care about anywhere in the function inside the function is "true", which is the default; and the default value selected is impossible to affect the correctness of the algorithm used. This is the reason why the use default parameter value is used.
For many functions, the right default is not found. For example, suppose you want to write a function to calculate the average of up to 5 INTs. You cannot use the default parameters, because the results of the function depends on the number of incoming parameters: If you pass 3 values, you must divide the total number of 3; if you pass 5 values, you must divide the total number 5. In addition, if the user does not provide a parameter, there is no "magical number" can be used as a default because all possible ints can be valid parameters. There is no choice if this case: must be overloaded:
Double AVG (INT A); Double AVG (Int A, Int B); Double AVG (Int A, Int B, INT C); Double AVG (Int A, Int B, INT C, INT D); Double AVG (INT A, INT B, INT C, INT D, INT E); Another case where the overload function is to complete a special task, but the algorithm depends on a given input value. This situation is very common for constructor: "Default" constructor constructs an object with air (no input), and the copy constructor is constructed according to an existing object:
// A class of Class Natural {public: natural (int initvalue); Natural (Const Natural & RHS);
PRIVATE: UNSIGNED INT VALUE
Void Init (INT INITVALUE); Void Error (Const String & MSG);
Inlinevoid Natural :: Init (int initvalue) {value = initValue;
Natural :: Natural (int initvalue) {if (initValue> 0) INIT (INITVALUE); Else Error ("Illegal Initial Value";}
INLINE NATURAL :: Natural (const natural); {..;}
The constructor input to the int is the error check, and the copy constructor does not need, so two different functions are required, which is overloaded. Also note that both functions must assign a new object. This will result in repetitive code in the two constructor, so you have to write a private member function init to solve this problem with the private member function init of "containing two constructor public code". This method - calls a "Overloaded Function" in the overload function - it is worth remembering because it is often useful (see clause 12).