Online Book Reader

Home Category

Professional C__ - Marc Gregoire [153]

By Root 1281 0
will skip to the matching #endif, which is usually placed at the end of the file. If the key has not been defined, the file will proceed to define the key so that a subsequent include of the same file will be skipped. This mechanism is also known as include guards.

#ifndef __LOGGER__

#define __LOGGER__

#include "Preferences.h"

class Logger

{

public:

static void setPreferences(const Preferences& inPrefs);

static void logError(const char* inError);

};

#endif // __LOGGER__

Code snippet from Headers\Logger.h

If your compiler supports the #pragma once directive (like Microsoft Visual C++ or GCC), this can be rewritten as follows:

#pragma once

#include "Preferences.h"

class Logger

{

public:

static void setPreferences(const Preferences& inPrefs);

static void logError(const char* inError);

};

Code snippet from Headers\LoggerPragmaOnce.h

These include guards or #pragma once directives also make sure that you don’t get duplicate definitions by including a header file multiple times. For example, suppose A.h includes Logger.h and B.h also includes Logger.h. If you have a source file called App.cpp which includes both A.h and B.h, the compiler will not complain about a duplicate definition of the Logger class because the Logger.h header will be included only once, even though A.h and B.h both include it.

Another tool for avoiding problems with headers is forward declarations. If you need to refer to a class but you cannot include its header file (for example, because it relies heavily on the class you are writing), you can tell the compiler that such a class exists without providing a formal definition through the #include mechanism. Of course, you cannot actually use the class in the code because the compiler knows nothing about it, except that the named class will exist after everything is linked together. However, you can still make use of pointers or references to the class in your class definition. In the following code, the Logger class refers to the Preferences class without including its header file.

#ifndef __LOGGER__

#define __LOGGER__

class Preferences; // forward declaration

class Logger

{

public:

static void setPreferences(const Preferences& inPrefs);

static void logError(const char* inError);

};

#endif // __LOGGER__

Code snippet from Headers\Logger.h

C UTILITIES


Recall that C++ is a superset of C, and thus contains all of its functionality. There are a few obscure C features which can occasionally be useful. This section examines two of these features: variable-length argument lists and preprocessor macros. There is no proper C++ alternative for preprocessor macros. However, C++11 does introduce a proper replacement for the old C-style variable-length argument lists.

Variable-Length Argument Lists

This section explains the old C-style variable-length argument lists. You need to know how these work because you might find them in older code. However, in new code you should use the type-safe C++11 variable-length argument lists using variadic templates, described in Chapter 20.

Consider the C function printf() from . You can call it with any number of arguments:

#include

int main()

{

printf("int %d\n", 5);

printf("String %s and int %d\n", "hello", 5);

printf("Many ints: %d, %d, %d, %d, %d\n", 1, 2, 3, 4, 5);

return 0;

}

Code snippet from VarArgs\PrintfDemo.cpp

C/C++ provides the syntax and some utility macros for writing your own functions with a variable number of arguments. These functions usually look a lot like printf(). Although you shouldn’t need this feature very often, occasionally you run into situations in which it’s quite useful. For example, suppose you want to write a quick-and-dirty debug function that prints strings to stderr if a debug flag is set, but does nothing if the debug flag is not set. This function should be able to print strings with arbitrary numbers and types of arguments. A simple implementation looks like this:

#include

#include

bool debug = false;

void debugOut(char* str, ...)

{

va_list

Return Main Page Previous Page Next Page

®Online Book Reader