A program needs provides variable declaration in C++ only at the time of its actual use. Although, in predecessor language C , the variable declaration happens at the start of an function. But, due to nature of objects, C++ becomes very special and therefore, there are reasons for this recommendation.
Why we should not do variable declaration in C++ at the start of function
There are 2 reasons for the same.
Getting complete initialization information for objects
In OOP, the objects may require extra information for initialization. The program may pass such information in constructor arguments. It is possible that either the arguments themselves or the information needed for such arguments is not available at the start of function call. Practically, such information may get available somewhere in middle during the execution of function.
If the C++ functions forcefully does all object’s declaration in first line of its definition, then it can be a wasteful approach. This is because the functions may need to re-initialize the object later. Additionally, objects shall need one additional assignment and getter/setter modifications again. This shall happens once the complete initialization information becomes available.
class MFRational
{
int inum;
int iden;
public:
Rational(int n=0, int d = 1) : inum(n), iden(d) {}
};
void doComputation( )
{
MFRational r1; // Default constructor for r1
int num;
int den;
cin >> num;
cin >> den;
r1 = getSquareRoot(num, den);//Assignment operator for r1
}
In the above example, the function doComputation should declare r1 only when both num and den are available. Such a strategy would have saved one extra constructor call that was done in first line of the function.
Avoiding unnecessary construction & destruction of objects
A function may exit very early due to corner-case scenarios. Some of the reasons are, like,
- Function arguments may violate some boundary condition, OR
- Function throws an exception in the middle.
In such cases, if the function constructs objects in first line, then all shall be destroyed without any use. This means both the construction and destruction were unnecessary. Therefore, all construction for objects have to wait, till the execution reaches a safe point in code.
void calculateInterst(int principle, int year, float interest )
{
SimpleInterest s1; //Will be destructed in exception
CompoundInterest c1; //Will be destructed in exception
if(year < 0 || interest < 0 || principle < 0)
throw 1;
//Actual calculation starts here
}
In above code, both the objects s1 and c1 were un-necessarily constructed in first line. Due to invalid inputs, both construction and destruction may prove very expensive. The problem shall become more critical when using complex containers like, vectors, list, etc.
Therefore, making the initialization wait makes the program more efficient.