Yes, we agree that the variables in the C language should be defined in the module header; but in C ++, we should cancel this practice. It is unnecessary, unnatural, and expensive.
Remember? If you define a variable of the type of constructor and destructor, when the program runs to the definition of the variable, it will inevitably face the constructor overhead; when the variable leaves its life space, it must bear the expenses of the analysis structure. This means that defining useless variables is accompanied by unnecessary overhead, so as long as possible, this situation should be avoided.
As I know, your programming method is elegant and sophisticated. So you may be thinking that you will never define a useless variable, so the suggestions in this article do not apply to your rigorous and compact programming style. Take a look at the following function: When the password is long enough, it returns the encrypted version of the password; when the password is too short, the function throws an exception of the logic_error type (the logic_error type is defined in the C ++ standard library, see clause 49 ):
// This function defines the variable "encrypted" too early"
String encryptpassword (const string & password)
{
String encrypted;
If (password. Length () <minimum_password_length ){
Throw logic_error ("password is too short ");
}
Perform necessary operations to encrypt the password version
Put in encrypted;
Return encrypted;
}
The object encrypted is not completely useless in the function, but it is useless if an exception is thrown. However, even if encryptpassword throws an exception (see the M15 clause), the program also bears the cost of encrypted construction and analysis. Therefore, it is best to postpone encrypted until it is actually needed:
// This function delays the definition of encrypted,
// Defined only when needed
String encryptpassword (const string & password)
{
If (password. Length () <minimum_password_length ){
Throw logic_error ("password is too short ");
}
String encrypted;
Perform necessary operations to encrypt the password version
Put in encrypted;
Return encrypted;
}
This code is not so rigorous, because the encrypted definition does not contain any initialization parameters. This causes the default constructor to be called. In most cases, what is the first thing to do for an object is to give it a value, which is usually implemented by a value assignment. Clause 12 illustrates why "constructing an object by default and assigning values to it" is much less efficient than "initializing this object with the desired value. This argument applies in the same way. For example, assume that the most difficult part of encryptpassword is in this function:
Void encrypt (string & S); // encrypted here
So encryptpassword can be implemented as follows (of course, it is not the best implementation method ):
// This function delays the definition of encrypted,
// It is defined only when necessary, but still inefficient.
String encryptpassword (const string & password)
{
... // Same as above, check the length
String encrypted; // Default Construction encrypted
Encrypted = password; // assign values to encrypted
Encrypt (encrypted );
Return encrypted;
}
A better way is to use password to initialize encrypted, bypassing unnecessary calls to the default constructor:
// The best way to define and initialize encrypted
String encryptpassword (const string & password)
{
... // Check the length
String encrypted (password); // you can copy the constructor to define and initialize the constructor.
Encrypt (encrypted );
Return encrypted;
}
This section describes the true meaning of the words "as much as possible" in the title of these terms. Not only do you need to postpone the definition of a variable until it must be used, but also try to postpone it until it can provide an initialization parameter. In this way, you can not only avoid the Construction and Analysis of unnecessary objects, but also avoid meaningless calls to the default constructor. In addition, when initializing a variable, the purpose of the variable itself is self-evident. Therefore, defining a variable here is helpful to indicate the meaning of the variable. Do you still remember the practices in C language? It is better to have a short comment next to the definition of each variable to indicate what the variable will do in the future. Now, with a proper name (see article 28) combined with meaningful initialization parameters, you can realize the dream of every programmer: eliminate unnecessary comments to a reliable variable.
Delaying variable definition can improve program efficiency, enhance program orderliness, and reduce comments on variable meanings. It seems that it is time to kiss the variable definitions of those open modules.