|
Elimination of the definition block
In C, you must
always define all the variables at the beginning of a block, after the opening
brace. This is not an uncommon requirement in programming languages, and the
reason given has often been that it’s “good programming
style.” On this point, I have my suspicions. It has always seemed
inconvenient to me, as a programmer, to pop back to the beginning of a block
every time I need a new variable. I also find code more readable when the
variable definition is close to its point of
use.
Perhaps these arguments are stylistic. In
C++, however, there’s a significant problem in being forced to define all
objects at the beginning of a scope. If a constructor exists, it must be called
when the object is created. However, if the constructor takes one or more
initialization arguments, how do you know you will have that initialization
information at the beginning of a scope? In the general programming situation,
you won’t. Because C has no concept of private, this separation of
definition and initialization is no problem. However, C++ guarantees that when
an object is created, it is simultaneously initialized. This ensures that you
will have no uninitialized objects running around in your system. C
doesn’t care; in fact, C encourages this practice by requiring you
to define variables at the beginning of a block before you necessarily have the
initialization
information[38].
In general, C++ will not allow you to
create an object before you have the initialization information for the
constructor. Because of this, the language wouldn’t be feasible if you had
to define variables at the beginning of a scope. In fact, the style of the
language seems to encourage the definition of an object as close to its point of
use as possible. In C++, any rule that applies to an “object”
automatically refers to an object of a built-in type as well. This means that
any class object or variable of a built-in type can also be defined at any point
in a scope. It also means that you can wait until you have the information for a
variable before defining it, so you can always
define and initialize at the
same time:
//: C06:DefineInitialize.cpp
// Defining variables anywhere
#include "../require.h"
#include <iostream>
#include <string>
using namespace std;
class G {
int i;
public:
G(int ii);
};
G::G(int ii) { i = ii; }
int main() {
cout << "initialization value? ";
int retval = 0;
cin >> retval;
require(retval != 0);
int y = retval + 3;
G g(y);
} ///:~
You can see that some code is executed,
then retval is defined, initialized, and used to capture user input, and
then y and g are defined. C, on the other hand, does not allow a
variable to be defined anywhere except at the beginning of the
scope.
In general, you should define variables
as close to their point of use as possible, and always initialize them when they
are defined. (This is a stylistic suggestion for built-in types, where
initialization is optional.) This is a safety issue. By reducing the duration of
the variable’s availability within the scope, you are reducing the chance
it will be misused in some other part of the scope. In addition, readability is
improved because the reader doesn’t have to jump back and forth to the
beginning of the scope to know the type of a
variable.
|
|