Online Book Reader

Home Category

Professional C__ - Marc Gregoire [144]

By Root 1513 0
it can use x. The compiler needs a declaration of x in order to use it in main(). However, if you declared x without the extern keyword, the compiler would think it’s a definition and would allocate space for x, causing the linkage step to fail (because there are now two x variables in the global scope). With extern, you can make variables globally accessible from multiple source files.

However, we do not recommend using global variables at all. They are confusing and error-prone, especially in large programs. For similar functionality, you should use static class members and methods.

static Variables in Functions

The final use of the static keyword in C++ is to create local variables that retain their values between exits and entrances to their scope. A static variable inside a function is like a global variable that is only accessible from that function. One common use of static variables is to “remember” whether a particular initialization has been performed for a certain function. For example, code that employs this technique might look something like this:

void performTask()

{

static bool inited = false;

if (!inited) {

cout << "initing\n";

// Perform initialization.

inited = true;

}

// Perform the desired task.

}

Code snippet from Static\StaticsInFunctions.cpp

However, static variables are confusing, and there are usually better ways to structure your code so that you can avoid them. In this case, you might want to write a class in which the constructor performs the required initialization.

Avoid using stand-alone static variables. Maintain state within an object instead.

Order of Initialization of Nonlocal Variables

Before leaving the topic of static data members and global variables, consider the order of initialization of these variables. All global variables and static class data members in a program are initialized before main() begins. The variables in a given source file are initialized in the order they appear in the source file. For example, in the following file Demo::x is guaranteed to be initialized before y:

class Demo

{

public:

static int x;

};

int Demo::x = 3;

int y = 4;

Code snippet from Static\order.cpp

However, C++ provides no specifications or guarantees about the initialization ordering of nonlocal variables in different source files. If you have a global variable x in one source file and a global variable y in another, you have no way of knowing which will be initialized first. Normally, this lack of specification isn’t cause for concern. However, it can be problematic if one global or static variable depends on another. Recall that initialization of objects implies running their constructors. The constructor of one global object might access another global object, assuming that it is already constructed. If these two global objects are declared in two different source files, you cannot count on one being constructed before the other, and you cannot control the order of initialization. This order may not be the same for different compilers or even different versions of the same compiler, and the order might even change by simply adding another file to your project.

Initialization order of nonlocal variables in different source files is undefined.

TYPES AND CASTS


The basic types in C++ are reviewed in Chapter 1, while Chapter 6 shows you how to write your own types with classes. This section explores some of the trickier aspects of types: typedefs, typedefs for function pointers, type aliases, and casts.

typedefs

A typedef provides a new name for an existing type declaration. You can think of a typedef simply as syntax for introducing a synonym for an existing type declaration without creating a new type. The following gives the new name IntPtr to the int* type declaration:

typedef int* IntPtr;

You can use the new type name and the definition it aliases interchangeably. For example, the following two lines are valid:

int* p1;

IntPtr p2;

Variables created with the new type name are completely compatible with those created with the original type declaration.

Return Main Page Previous Page Next Page

®Online Book Reader