Effective C++ 32: Postpone variable definitions as long as possible
Most of us are told to define variables at the beginning of a block when we are learning C programming language. Defining all variables at the beginning of a block makes the code look tight and lean. But in the same time, the bunches of variables drive code readers crazy. What is this variable standing for? When will that variable be used? So it is quite normal to write comments for every variable in the C world.
What about the world of C++? In C++, the advice is to postpone variable definitions as long as possible. Objects in C++ are constructed using constructors and destructed using destructors, both of which cost time. And if we define all variables at the beginning, we may define some objects that are not used at all, thus pay unnecessary costs.
Consider the following code:
// this function defines the variable "encrypted" too soon
string encryptPassword(const string& password)
{
string encrypted;
if (password.length() < MINIMUM_PASSWORD_LENGTH) {
throw logic_error("Password is too short");
}
do whatever is necessary to place an encrypted
version of password in encrypted;
return encrypted;
}
The string encrypted is defined too soon. If an exception is thrown, encrypted will not be used.
We can write the code like this:
// this function postpones "encrypted"'s definition until
// it's necessary, but it's still needlessly inefficient
string encryptPassword(const string& password)
{
... // check length as above
string encrypted; // default-construct encrypted
encrypted = password; // assign to encrypted
encrypt(encrypted);
return encrypted;
}
However, this still is not the best way. Here is a more efficient way:
// finally, the best way to define and initialize encrypted
string encryptPassword(const string& password)
{
... // check length
string encrypted(password); // define and initialize
// via copy constructor
encrypt(encrypted);
return encrypted;
}