As long as a variable is defined, and its type carries a constructor or destructor,
When the control flow of the Program reaches the definition of this variable, the variable will bear the construction cost; when the variable leaves the scope, it will bear the composition cost.
// This function prematurely defines the variable "encrypted"
STD: String encryptpassword (const STD: string & password)
{
Using namespace STD;
String encrypted;
If (password. Length () <minimumpasswordlengt)
{
Throw logic_error ("password is too short ")
}
... // Perform necessary actions to put an encrypted password into encrypted.
Return enpolicted;
}
If the function encryptpassword throws an exception, you still have to pay for the encrypted construction and analysis structure. So it is better to delay the definition of encrypted. Wait until you confirm that you need it:
// This function delays the definition of "encrypted" until it is actually needed.
STD: String encryptpassword (const STD: string & password)
{
Using namespace STD;
If (password. Length () <minimumpasswordlengt)
{
Throw logic_error ("password is too short ")
}
String encrypted;
... // Perform necessary actions to put an encrypted password into encrypted.
Return enpolicted;
}
Although defined, encrypted does not have any parameter as the initial value. This means that the default constructor is called. In many cases, the first action you perform on this object is to give it a value, which is usually done by assigning values.
Void encrypt (STD: string & S );
STD: String encryptpassword (const STD: string & password)
{
Using namespace STD;
If (password. Length () <minimumpasswordlengt)
{
Throw logic_error ("password is too short ")
}
STD: String encrypted; // default-construct encrypted
Encrypted = password; // value to encrypted
Encrypt (encrypted );
Return enpolicted;
}
A more popular practice is to use password as the initial value of encrypted and skip the meaningless default constructor process:
STD: String encryptpassword (const STD: string & password)
{
Using namespace STD;
If (password. Length () <minimumpasswordlengt)
{
Throw logic_error ("password is too short ")
}
STD: String encrypted (password); // use the copy constructor to define and initialize.
Encrypt (encrypted );
Return enpolicted;
}
The meaning of "delay as much as possible. Not only should the definition of the variable be delayed until the previous moment before the variable has to be used, but the definition should be delayed even until the initial value parameter can be given to the variable. It not only avoids unnecessary objects (and destructor), but also avoids meaningless default constructor behavior.
For loops:
// Method A: defined outside the loop
Widget W;
For (INT I = 0; I <n; I ++)
{
W = depends on the value of an I;
...
}
// Method B: defined in the loop
For (INT I = 0; I <n; I ++)
{
Widget W (depending on a value of I );
...
}
Practice A: 1 constructor + 1 destructor + N assignments
Practice B: N constructor + N Constructor
If 1. The assignment cost is lower than the "Construction + destructor" cost, 2. the assignment is processing highly sensitive parts; otherwise, B should be used;
In B, W has a smaller scope than in A, which is more conducive to program comprehension and maintainability.