Object Oriented Programming in C

来源:百度文库 编辑:神马文学网 时间:2024/04/28 01:48:47
Embedded software development is slowly moving towards object orientedanalysis, designand programming. The introduction of object oriented technologies in somesystems has not happened due to lack of C++ support on some platforms.
This article focuses on platforms where C++ compilers are not available. Thedevelopers working on these platforms should still be able to use objectoriented analysis and design. When it comes to final code development they canuse C.
The following sections cover an example of C++ code and its implementation inC.
C++ Source Code: C++ source files implementing TerminalManager and Terminal classes.
C Source Code: TerminalManager and Terminal implemented in C for a platform that does not support C++.
Terminal Manager and Terminal C++ header and source files are shownbelow:
Terminal Manager
TerminalManager.hpp
// TerminalManager header file. We will be using this class
// as an example for Object Oriented Programming in C.
#include "Terminal.hpp"
class TerminalManager
{
private:
enum {MAX_TERMINALS=500};
Terminal terminals[MAX_TERMINALS];
Terminal *FindTerminal(int terminalId);
public:
TerminalManager();
~TerminalManager();
void HandleMessage(Msg* pMsg);
};
TerminalManager.cpp
// TerminalManager source file. We will be using this class
// as an example for Object Oriented Programming in C.
#include
#include "TerminalManager.hpp"
#include "Msg.hpp"
TerminalManager::TerminalManager()
{
//...
}
TerminalManager::~TerminalManager()
{
}
void TerminalManager::HandleMessage(Msg* pMsg)
{
int status, status1;
int terminalId = pMsg->GetTerminalId();
Terminal *pTerm = FindTerminal(terminalId);
Terminal *pOtherTerm = NULL;
if (pTerm != NULL)
{
switch (pMsg->GetType())
{
case CREATE_TERMINAL:
pTerm->Activate((const TerminalCreateMsg *)pMsg);
break;
case DELETE_TERMINAL:
pTerm->Deactivate((const TerminalDeleteMsg *) pMsg);
break;
case RUN_DIAGNOSTICS:
status = pTerm->HandleRunDiagnostics((const RunDiagnosticsMsg *) pMsg);
break;
case PERFORM_SWITCHOVER:
pOtherTerm = FindTerminal(pMsg->GetOtherTerminalId());
status = pTerm->HandleOutOfService();
status1 = pOtherTerm->HandleInService();
break;
}
}
delete pMsg;
}
Terminal *TerminalManager::FindTerminal(int terminalId)
{
if (terminalId < MAX_TERMINALS)
{
return (&terminals[terminalId]);
}
else
{
return NULL;
}
}
Terminal
Terminal.hpp
// Terminal class header file.
// Forward declaration for messages
class TerminalCreateMsg;
class TerminalDeleteMsg;
class RunDiagnosticsMsg;
class Msg;
// Terminal class
class Terminal
{
enum { UNKNOWN = 0 };
enum {OUT_OF_SERVICE=1, INSERVICE=2};
//...
int terminalId;
int terminalType;
int terminalStatus;
void SendMessage(Msg *pMsg);
public:
void Activate(const TerminalCreateMsg *pMsg);
void Deactivate(const TerminalDeleteMsg *pMsg);
int HandleRunDiagnostics(const RunDiagnosticsMsg *pMsg);
int HandleOutOfService();
int HandleInService();
Terminal();
~Terminal();
};
Terminal.cpp
// Terminal class source file.
#include "Terminal.hpp"
#include "Msg.hpp"
void Terminal::SendMessage(Msg *pMsg)
{
//...
}
Terminal::Terminal()
{
terminalId = UNKNOWN;
terminalType = UNKNOWN;
terminalStatus = UNKNOWN;
}
Terminal::~Terminal()
{
//...
}
int Terminal::HandleRunDiagnostics(const RunDiagnosticsMsg *pMsg)
{
int status = 1;
//...
return status;
}
int Terminal::HandleOutOfService()
{
int status = 1;
terminalStatus = OUT_OF_SERVICE;
//...
return status;
}
int Terminal::HandleInService()
{
int status = 1;
terminalStatus = INSERVICE;
//...
return status;
}
void Terminal::Activate(const TerminalCreateMsg *pMsg)
{
terminalId = pMsg->GetTerminalId();
terminalType = pMsg->GetTerminalType();
terminalStatus = pMsg->GetTerminalStatus();
//...
TerminalCreateAck *pAck = new TerminalCreateAck(terminalId, terminalStatus);
SendMessage(pAck);
}
void Terminal::Deactivate(const TerminalDeleteMsg *pMsg)
{
//...
terminalId = UNKNOWN;
terminalType = UNKNOWN;
terminalStatus = UNKNOWN;
//...
}
Msg.hpp
// Messages used by the Terminal and TerminalManager classes.
enum MsgType
{
CREATE_TERMINAL,
DELETE_TERMINAL,
RUN_DIAGNOSTICS,
PERFORM_SWITCHOVER
};
class Msg
{
//...
int msgType;
int terminalType;
int terminalId;
int otherTerminalId;
int terminalStatus;
public:
MsgType GetType() const;
int GetTerminalId() const;
int GetOtherTerminalId() const;
int GetTerminalType() const;
};
// Message used to create a terminal
class TerminalCreateMsg : public Msg
{
public:
int GetTerminalStatus() const;
};
// Acknowledgement to Terminal Create message.
class TerminalCreateAck : public Msg
{
public:
TerminalCreateAck(int terminalId, int terminalStatus);
};
// Terminal Delete message
class TerminalDeleteMsg : public Msg
{
};
Terminal Manager and Terminal C header and source files are shown below. Theimportant points to note are:
Data members of a class map to C structures
Methods of a class map to C functions with the "data member" structure pointer as the first parameter.
TerminalManager
TerminalManager.h
/*
TerminalManager header file. We will be using this class
as an example for Object Oriented Programming in C.
*/
#include "Terminal.h"
#define MAX_TERMINALS 500
/* Structure contains all data used by the Terminal Manager. */
typedef struct
{
Terminal terminals[MAX_TERMINALS];
} TerminalManager;
/*
ANSI C Function prototypes of all functions that operate
on the TerminalManager structure.
*/
void TerminalManager_Construct(TerminalManager *pMgr);
void TerminalManager_Destroy(TerminalManager *pMgr);
void TerminalManager_HandleMessage(TerminalManager *pMgr, Msg* pMsg);
Terminal Manager.c
/*
TerminalManager source file. We will be using this class
as an example for Object Oriented Programming in C.
*/
#include
#include "TerminalManager.h"
#include "Msg.h"
#include
Terminal *TerminalManager_FindTerminal(TerminalManager *pMgr, int terminalId)
{
if (terminalId < MAX_TERMINALS)
{
return (&(pMgr->terminals[terminalId]));
}
else
{
return NULL;
}
}
void TerminalManager_Construct(TerminalManager *pMgr)
{
int i;
/*
C will not call construction functions, so loop through all call the
construction functions for all terminals.
*/
for (i=0; i < MAX_TERMINALS; i++)
{
Terminal_Construct(&(pMgr->terminals[i]));
}
}
void TerminalManager_Destroy(TerminalManager *pMgr)
{
int i;
/*
C will not call destruction functions, so loop through all call the
destruction functions for all terminals.
*/
for (i=0; i < MAX_TERMINALS; i++)
{
Terminal_Destroy(&(pMgr->terminals[i]));
}
}
void TerminalManager_HandleMessage(TerminalManager *pMgr, Msg* pMsg)
{
int status, status1;
int terminalId = pMsg->terminalId;
Terminal *pTerm = TerminalManager_FindTerminal(pMgr, terminalId);
Terminal *pOtherTerm = NULL;
/*
Switch on the message type and invoke the Terminal's message handlers for
the terminal specified in the message. Here the terminal manager takes
care of indexing into the terminal structure and it passes the pointer
to the terminal handler functions. Due to this design, implementation
of the terminal handler functions just focus on handling the specified
terminal.
*/
if (pTerm != NULL)
{
switch (pMsg->msgType)
{
case CREATE_TERMINAL:
Terminal_Activate(pTerm, (const TerminalCreateMsg *)pMsg);
break;
case DELETE_TERMINAL:
Terminal_Deactivate(pTerm, (const TerminalDeleteMsg *) pMsg);
break;
case RUN_DIAGNOSTICS:
status = Terminal_HandleRunDiagnostics(pTerm, (const RunDiagnosticsMsg *) pMsg);
break;
case PERFORM_SWITCHOVER:
pOtherTerm = TerminalManager_FindTerminal(pMgr, pMsg->otherTerminalId);
status = Terminal_HandleOutOfService(pTerm);
status1 = Terminal_HandleInService(pOtherTerm);
break;
}
}
free(pMsg);
}
Terminal
Terminal.h
/* Terminal struct header file. */
#include "Msg.h"
#define UNKNOWN 0
#define OUT_OF_SERVICE 1
#define INSERVICE 2
/* Terminal struct */
typedef struct
{
/*...*/
int terminalId;
int terminalType;
int terminalStatus;
} Terminal;
/*
Prototypes for Terminal structure related functions. Helper
functions needed by these functions are marked static are not
included here.
*/
void Terminal_Activate(Terminal *pTerm, const TerminalCreateMsg *pMsg);
void Terminal_Deactivate(Terminal *pTerm, const TerminalDeleteMsg *pMsg);
int Terminal_HandleRunDiagnostics(Terminal *pTerm, const RunDiagnosticsMsg *pMsg);
int Terminal_HandleOutOfService(Terminal *pTerm);
int Terminal_HandleInService(Terminal *pTerm);
void Terminal_Construct(Terminal *pTerm);
void Terminal_Destroy(Terminal *pTerm);
Terminal.c
/* Terminal struct source file. */
#include "Terminal.h"
#include "Msg.h"
#include
/*
Terminal_SendMessage is not visible to outside the Terminal.c file.
This is equivalent to a private method in C++.
*/
static void Terminal_SendMessage(Terminal *pTerm, Msg *pMsg)
{
/*...*/
}
void Terminal_Construct(Terminal *pTerm)
{
pTerm->terminalId = UNKNOWN;
pTerm->terminalType = UNKNOWN;
pTerm->terminalStatus = UNKNOWN;
}
void Terminal_Destroy(Terminal *pTerm)
{
/*...*/
}
int Terminal_HandleRunDiagnostics(Terminal *pTerm, const RunDiagnosticsMsg *pMsg)
{
int status = 1;
/*...*/
return status;
}
int Terminal_HandleOutOfService(Terminal *pTerm)
{
int status = 1;
pTerm->terminalStatus = OUT_OF_SERVICE;
/*...*/
return status;
}
int Terminal_HandleInService(Terminal *pTerm)
{
int status = 1;
pTerm->terminalStatus = INSERVICE;
/*...*/
return status;
}
void Terminal_Activate(Terminal *pTerm, const TerminalCreateMsg *pMsg)
{
TerminalCreateAck *pAck;
pTerm->terminalId = pMsg->header.terminalId;
pTerm->terminalType = pMsg->header.terminalType;
pTerm->terminalStatus = pMsg->header.terminalStatus;
/*...*/
pAck = (TerminalCreateAck *)malloc(sizeof(TerminalCreateAck));
pAck->header.terminalId = pTerm->terminalId;
pAck->header.terminalStatus = pTerm->terminalStatus;
Terminal_SendMessage(pTerm, (Msg *)pAck);
}
void Terminal_Deactivate(Terminal *pTerm, const TerminalDeleteMsg *pMsg)
{
/*...*/
pTerm->terminalId = UNKNOWN;
pTerm->terminalType = UNKNOWN;
pTerm->terminalStatus = UNKNOWN;
/*...*/
}
Msg.h
/* Messages used by the Terminal and TerminalManager classes. */
#ifndef MSG_H
#define MSG_H
enum MsgType
{
CREATE_TERMINAL,
DELETE_TERMINAL,
RUN_DIAGNOSTICS,
PERFORM_SWITCHOVER
};
typedef struct
{
/*...*/
int msgType;
int terminalType;
int terminalId;
int otherTerminalId;
int terminalStatus;
} Msg;
/* Message used to create a terminal. */
typedef struct
{
Msg header;
}TerminalCreateMsg;
/* Acknowledgement to Terminal Create message. */
typedef struct
{
Msg header;
} TerminalCreateAck;
/* Terminal Delete message */
typedef struct
{
Msg header;
} TerminalDeleteMsg;
typedef struct
{
Msg header;
} RunDiagnosticsMsg;
#endif
Explore More
Compare C++ and the equivalent C code for class declarations and method invocation
Compare C++ and the equivalent C code for inheritance and virtual functions.