Файл: Interfacing with C plus plus-programing communication with microcontrolers (K. Bentley, 2006).pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 14.06.2025

Просмотров: 3567

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

9 PROGRAM DEVELOPMENT TECHNIQUES 285

Object-oriented and non-object-oriented programs differ; in one case the functions are member functions, and in the other case all the functions are non-member functions. It is also possible for an object-oriented program to use a combination of the two cases. Its header file may contain a class definition and also some nonmember function declarations.

If non-member C/C++ functions are to be used in the program, it is general practice to put the declarations of such functions into a header file and then to include that header file at the top of the source file. The definitions of the non-member functions may be provided in a separate function file in much the same way as the member functions of a particular class. The function file in its .obj/.lib form will be needed at linking time.

9.3.2 Generating a Multiple File Program

Even inside a header file, the header file corresponding to each object used (in this header file) is included.

#include <stdlib.h>

#include “motor.h”

Header files

are

#include “dcmotor.h”

included for

#include “stepper.h”

each object

void main()

used.

{

.

.

.

}

User Program (main.cpp)

#include “motor.h”

class DCMotor : public Motor

{

public:

DCMotor(int baseaddress=0x378); virtual void Forward();

virtual void Reverse(); virtual void Brake(); virtual void Off();

};

DCMotor class header file (dcmotor.h)

Figure 9-3 Use of include directives.

As mentioned previously, whenever an object from a class is needed within a program, its class header file needs to be included in the program before the object can be used. The compiler will first interpret the class definition (from the first header file encountered) and then check that the class has been implemented correctly throughout the remainder of the program. The program will only compile correctly if the programmer has made function calls that are compatible with the function declarations in the header files. Figure 9-3 shows the use of the Motor, DCMotor, and StepperMotor objects in the User Program, evident by the inclusion of their class header files.


286 9 PROGRAM DEVELOPMENT TECHNIQUES

The structure of DCMotor

class member functions must conform to the function declarations given in the dcmotor.h file.

Class definition

// class definition

#include “motor.h”

class DCMotor : public Motor

{

public:

DCMotor(int baseaddress=0x378); virtual void Forward();

virtual void Reverse(); virtual void Brake(); virtual void Off();

Header File (dcmotor.h)

Member function definitions

#include “dcmotor.h”

// member f’n 1 definition DCMotor::DCMotor(..

{

.

.

.

}

// member f’n 2 definition DCMotor::Forward()

{

.

.

.

}

// member f’n 3 definition DCMotor::Reverse()

{

.

.

.

}

.

.

.

.

.

.

Function File (dcmotor.cpp or *.obj or *.lib)

Figure 9-4 Include header file in the function file of its class.

Figure 9-4 shows the inclusion of the header file for the DCMotor class at the start of the function file for the DCMotor class. This will ensure all member function definitions of the DCMotor class (that were derived from the Motor class and overridden as required) will conform with the function declarations stipulated in the header file dcmotor.h.


9 PROGRAM DEVELOPMENT TECHNIQUES 287

Include directives

The files that are included from the ‘include’ directory of the C/C++ program development software are enclosed between angle brackets angle brackets (< >):

#include <stdlib.h> // For standard C library fn’s

Header files included from the same directory or any other directory in the path are enclosed between double quotation marks (“ “):

#include “motor.h” // For motor class objects used.

The proper use of angle brackets and double quotation marks is crucial as it allows the compiler to efficiently locate the included header files during compilation and linking.

Preventing Multiple Inclusions of Header Files

A particular header file is included only once in a program. Should a header file be included more than once, the compiler will interpret this as an error and issue an error message. The compiler can interpret multiple inclusion as, for example, the redefinition of a class that is already defined by the first instance of the include file

– hence the error!

The general rule “Include the header file of the object you use in the program” may lead to multiple inclusions. For example, if a program uses a DCMotor object and a StepperMotor object, we must include dcmotor.h as well as stepper.h files. They both have motor.h included in them. As a result motor.h will be included twice. There is a mechanism that enables us to practice the general rule above and at the same time avoid multiple inclusions of the same header file. The procedure uses a ‘status flag’, explained as follows:

Before the preprocessor begins to include header files, the flag will be inactive (file not included).

The first time a particular header file is presented for inclusion, the flag will be tested, and the result will indicate that the header file has not been included. The header file will be included this time and the flag will then be activated, indicating inclusion has now taken place.

When this header file is presented for inclusion on subsequent occasions, the flag will be tested and its status (this time; file included) will direct the preprocessor to ignore this file, preventing any multiple inclusions.

Sentries for header files

Sentries in header files are compiler directives for the preprocessor. They implement the function of the ‘status flag’ just described and prevent the compiler from including the same header file more than once.

The following example uses the AbstactMotor class to show how sentries are added to a header file.

288 9 PROGRAM DEVELOPMENT TECHNIQUES

Listing 9-6 AbsMotor.h header file.

#ifndef AbsmotorH #define AbsmotorH

class AbstractMotor

{

private:

int Speed;

public:

AbstractMotor();

void SetSpeed(int speed); int GetSpeed();

virtual void Off()=0; virtual void Forward()=0; virtual void Reverse()=0; virtual void Brake()=0; virtual ~AbstractMotor(){}

};

#endif

The first preprocessor directive #ifndef represents ‘if not defined’. It is similar to an if statement, with its body starting at #ifndef and ending at the line with the directive #endif. Therefore, the preprocessor interprets:

#ifndef AbsmotorH

as ‘if AbsmotorH is not defined’. The body of this #if statement will be executed only if AbsmotorH is not defined.

The identifier AbsmotorH will not be defined when proceeding to process a multiple file program for the first time. As such, when the pre-processor encounters the line #ifndef AbsmotorH, it will enter the body of the #if statement. The first line within the body is:

#define AbsmotorH

The #define directive is used to state that identifier AbsmotorH is to be defined. The identifier must be unique and not already used to name another header file from a different class. Improper naming of identifiers can lead to programming bugs that are difficult to find. Since the file system of your computer maintains unique names for each file, the best practice is to derive the sentry name based on the name of that header file. This approach has been used to form the name of the AbsmotorH sentry from the associated header file absmotor.h. When all remaining lines in the body are processed by the pre-processor, the AbstractMotor class will be interpreted by the compiler and the sentry AbsMotorH defined. Should the pre-processor encounter another absmotor.h


9 PROGRAM DEVELOPMENT TECHNIQUES 289

file included in another file of that program, execution of the #ifndef AbsmotorH directive will return false. In this case the body of the #if statement will be skipped, avoiding a repeated inclusion of its contents.

9.4 Case Study - Motor Driver Program

This section will demonstrate the process of generating a multiple file program as described previously using the motor driver program developed in Chapter 8. We will first create the software modules for each object class in our program. Each module will have its own header file and function file.

ParallelPort Class

ParallelPort Class Defn’s

AbstractMotor Class

AbstractMotor Class Defn’s

Motor Class

Motor Class Defn’s

StepperMotor Class

StepperMotor Class Defn’s

DCMotor Class

DCMotor Class Defn’s

dcmotor.h

ParallelPort Function File

AbstractMotor Function File

User Program

Motor Function File

StepperMotor Function File

DCMotor Function File

main.cpp

Single file program

dcmotor.cpp

Figure 9-5 Form a multiple file program.

Figure 9-5 shows the original single file program on the left with its main function and classes. The header file and function file associated with each class is shown on the right. The program from Chapter 8 (Listing 8-19) is shown following. Each code segment has been identified from the program, copied and labelled to its appropriate file type; being a header file or function file. These files are then saved with *.h and *.cpp extensions, preferably in the same directory to minimise file search time.