⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chapter2.htm

📁 嵌入式软件开发.rar
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<head>
<title>Chapter 2 Object Oriented Programming in C</title>
</head>
<body>

<h1>Object Oriented Programming in C</h1>
<h4>Special Heading For HTML Version</h4>
<strong><p>This Chapter contains links to the definitions of each new Object Oriented
Programming word.  There may seem to be an excessive number of links to the same
location.  However, anyone reading this chapter who sees an unusual word anywhere in
the text will be able to jump to its definition with a point and click.</strong> 
<p>
	Why would we want to do object oriented programming in C?  There is one 
overwhelming reason that we cannot overlook.  Today, there are no C++ compilers for 
our microcontrollers!  The only approach to use C++ is to compile the C++ program with 
a cfront.  A cfront is a compiler that compiles C++ code into C code.  The resultant code 
can be then compiled with a C compiler.  A cfront will produce code aimed to be used on 
a large computer, and it is not too forgiving of the many tricks that are usually employed 
in C to permit the code to run on a microcontroller.  Therefore, a clear alternative to 
writing code in C++ is to write object oriented code in C.  In many cases, C can do the 
same job as C++.  There are clearly some features of C++ that must be lost when C is 
used to code OOP.  Recall the three key words of OOP are <a href="chapter1.htm#encapsulation">encapsulation</a>, <a href="chapter1.htm#inheritance">inheritance</a>, and 
<a href="chapter1.htm#polymorphism">polymorphism</a>.  With only a few compromizes,OOP code in C retains most of these 
capabilities.  The features that are lost are both operator and function overloading and the 
protection modes of C++. We will see several examples of object oriented programming in 
C and will examine the costs of doing our business in this language.  Some features are 
completely lost, some are impared, but many are still available and can be used to great 
advantage without the need for a C++ compiler.

<h2><a name="classes"><a href="chapter1.htm#class">Classes</a>, 
<a href="chapter1.htm#object">Objects</a> and <a href="chapter1.htm#encapsulation">Encapsulation</a></a></h2>
<p>
	An object is usually considered a memory storage location.  It will still be true in 
OOP written in C.  In Chapter 1, we saw a class which was described as an object 
template.  Here we will use the structure to create our object template.  To begin, we will 
use a structure that contains all of the necessary data for the object.  Associated with the 
object are the several functions needed to manipulate the <a href="chapter1.htm#attribute">attribute</a>s of the object.  Let us 
choose a very simple object that we can explore easily.  The object in this case is going to 
be a counter.  The counter has only one <a href="chapter1.htm#attribute">attribute</a>: the number of the count.  This counter 
will work like a hand held counter used by a theater usher who counts the number of 
people entering a theater.  The counter content can be incremented and it may be read.  
The <a href="chapter1.htm#attribute">attribute</a> is the count, and there are two <a href="chapter1.htm#method">method</a>s associated with the counter:  
increment and query.
<p> 
	Shown below is a <a href="chapter1.htm#header">header file</a> named defines.h.  This file is short and requires  little 
explanation here.  Several of the important defined constants needed in our programs are 
identified here, and the <a href="appendxb.htm#defines">defines.h</a> header can be included at the beginning of each file to 
create these definitions for each program module.  
<p>
 <pre>
	#ifndef DEFINES_H
	#define DEFINES_H

	#ifndef NULL
		#define NULL (void *)0
	#endif
	#define EOM 0
	#define FOREVER while(TRUE) 

	typedef int Boolean;
	typedef unsigned int WORD;
	typedef unsigned char BYTE;

	enum {FALSE,TRUE};
	enum {OFF,ON};
	enum {NO,YES};
	enum {FAST,SLOW};

	enum errors 
	{
		SEMAPHORE,
		SERIAL,
		TIMER,
		DELAY,
		PWM
	};

	enum edges
	{
		DISABLE,
		RISING,
		FALLING,
		ANY
	};

	enum outputs
	{
		DISCONNECT,
		TOGGLE,
		CLEAR,
		SET
	};	

	#endif
</pre>
 
<p>	Note that the header starts with two lines 
<pre>
 
	#ifndef DEFINES_H
	#define DEFINES_H
</pre>
 
<p>
Also note that the last line of the file is 
<pre> 
	#endif
</pre> 
These simple commands will cause any multiple inclusion of this file to be ignored.  
Therefore, there will be no multiple definitions of symbols found in the file regardless of 
the number of times that the file is included in different modules when the program is 
compiled.  All <a href="chapter1.htm#header">header file</a>s should be protected from multiple inclusion by this simple 
mechanism.  Most of the remainder of the defines.h <a href="chapter1.htm#header">header file</a> contents is self explanatory.  
The parameter NULL is not defined by the language.  We define it here as a pointer to a 
type void, and the pointer has a zero value.    This definition is protected by an #ifndef test 
to assure that there is no more than one inclusion of the definition for a NULL in a 
program.  The macro FOREVER is very useful in most main programs for embedded 
systems.  There are several enumerates that are convenient to simply define, and assign 
values to constant names needed through the book.  The various items enumerated and 
macros defined are needed in typical programs.  The enumeration that defines SERIAL, 
TIMER, etc. is needed for the system error handler that will be discussed in Chapter 4.  
The enumerations edges and outputs contain values helpful in writing code for the input 
caputre system and the output compare system.
<p>  
	Shown below is the <a href="chapter1.htm#header">header file</a> for our simple counter.  
This <a href="chapter1.htm#header">header file</a> contains 
the protection from multiple inclusions and an include command to include the defines.h 
header in the program.  Next, the header contains a typedef command for a structure type. 
The structure type has no tag name, but the structure is given a type name Counter.  This
structure contains only one member called count.  count is of the type WORD which is 
identified by a typedef command in defines.h as an unsigned int. 																												                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
<pre>
 
	#ifndef COUNTER_H
	#define COUNTER_H

	#include "defines.h"

	struct
	{
	    WORD count;
	}Counter;

	void increment(void);
	int query(void);

	#endif
</pre>
 
<p>
	Also found in the <a href="chapter1.htm#header">header file</a> are two function prototypes.  You will note that there 
is no function code for these functions in the <a href="chapter1.htm#header">header file</a>.  In OOP talk, this file is called the 
class <a href="chapter1.htm#header">header file</a>.  Such files should never contain executable code.  All executable code 
associated with a class is included in the class <a href="chapter1.htm#implementation_file">implementation</a> file.  
The class 
<a href="chapter1.htm#implementation_file">implementation file</a> for our counter class is shown below.  The <a href="chapter1.htm#header">header file</a> that contains the 
above header is called counter0.h.  
<pre>
 
	#include "counter0.h"

	void increment(void)
	{
	    Counter.count++;
	}

	int query(void)
	{
	    return Counter.count;
	}
</pre>
 
<p>
	The <a href="chapter1.htm#implementation_file">implementation file</a> first includes the appropriate <a href="chapter1.htm#header">header file</a>.  The remainder of 
the code found in this file is executable code.  The two functions found here are 
increment() and query().  Recall that these function prototypes are included in the header 
file.  This particular program structure follows C++ closely.  If the programmer wishes to 
build a library of objects, it is possible to deliver to a customer a readable version of the 
<a href="chapter1.htm#header">header file</a>s and a compiled version of the <a href="chapter1.htm#implementation_file">implementation file</a>s.  The way the objects can 
be used can be seen from the contents of the <a href="chapter1.htm#header">header file</a>, and the details of how the  
objects work are hidden in the <a href="chapter1.htm#implementation_file">implementation file</a>.  Therefore, the programmer can sell 
the product with assurance that the program details are hidden from the user.
<p>
	The two functions in this case perform simple actions.  increment() causes the 
member count in the object Counter  to be incremented, and query() returns the value of 
the member count to the calling program.  A program that will test the performance of this 
object is shown below.
<pre>
 
	#include "counter0.h"
	#include &lt;stdio.h&gt;

	main()
	{
	    int i;
	    
	    for(i=0;i&lt;12;i++)
	        increment();
	    printf("a=%d \n",query());
	}
</pre>
 
<p>
In this program, it is assumed that counter0.c has been compiled and the compiled version 
is linked  with the above program when it is compiled.  The result of execution of this 
program is
<pre>
 
    a=12
</pre>
 
<p>
as expected.  
<p>
	Let us examine this program in a little more detail to determine what we have and 
have not accomplished.  First of all, Counter is an object.  From an <a href="chapter1.htm#encapsulation">
encapsulation </a>
standpoint, counter does not meet the test.  The <a href="chapter1.htm#attribute">attribute</a> count is accessed by the class 
<a href="chapter1.htm#method">method</a>s.  There is, however, no mechanism that prevents any portion of the program from 
accessing count once the object has been created.  This portion of <a href="chapter1.htm#encapsulation">encapsulation</a>, <a href="chapter1.htm#attribute">attribute</a> 
hiding, is not a part of and cannot be easily implemented by C.    All programmers must 
agree to access object <a href="chapter1.htm#attribute">attribute</a>s through the <a href="chapter1.htm#method">method</a>s provided with the class only 
<p>	Additionally, there is another difficulty.  One would expect that the programmer 
should be able to create several instances of the object Counter.  On the contrary, Counter 
in this case is in itself an instance of a structure, and no mechanism is avaliable for creating 
additional instances.  You will observe that the two <a href="chapter1.htm#method">method</a>s increment() and query() both 
operate on the member count in the structure Counter.  If other versions of Counter were 
available, increment() and query() would have no means for accessing these other 
instances.  To be practical, it is necessary that our class approach allow the instantiation of 
several different instances of Counter, and the <a href="chapter1.htm#method">method</a>s must access the individual instance 
that the programmer needs.  
<p>	These problems are easily addressed.  The <a href="chapter1.htm#method">method</a>s will each have an argument 
that is a pointer to the individual object that is being accessed.  A <a href="chapter1.htm#header">header file</a> for the class 
Counter that implements this approach is shown below.  Note here that a typedef 
construct is used to create the type Counter.  This type contains only one WORD member.  
The function prototypes for both increment() and query() now contain arguments that are 
pointers to the type Counter.  When using this approach, we need a means to create an 
instance of  Counter, or a pointer to the type Counter, and delete a specified instance.  The 
function count_()--single underscore--is the <a href="chapter1.htm#constructor">constructor</a>
 for the object Counter.  This 
function will create an instance of Counter and return a pointer to that specific instance to 
the calling program.  The <a href="chapter1.htm#destructor">destructor</a> is count__(), double 
underscore.  This function is 
executed with an argument that is a pointer returned from count_().  The <a href="chapter1.htm#destructor">destructor</a> will 
destroy the specific instance of Count.  We shall append a single underscore to the name 
of a <a href="chapter1.htm#constructor">constructor</a> and a double underscore to the name of a <a href="chapter1.htm#destructor">destructor</a> throughout this text.
<pre>
 
	#ifndef COUNTER_H
	#define COUNTER_H

	#include "defines.h"

	typedef struct
	{
	    WORD count;
	}Counter;                                                        

	void increment(Counter *);
	int query(Counter *);

	Counter *counter_(void);
	void counter__(Counter *);

	#endif
</pre>
 
<p>
Both of these functions exist in C++.  Either can be defined as we will do here, or the 
language provides a default version of both the <a href="chapter1.htm#destructor">destructor</a> and the <a href="chapter1.htm#constructor">constructor</a>.  C requires 
that the program provide the <a href="chapter1.htm#constructor">constructor</a> and <a href="chapter1.htm#destructor">destructor</a>.  It is important that the program 
create each object when it is needed, and it is equally important that the object be 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -