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

📄 chapter2.htm

📁 嵌入式软件开发.rar
💻 HTM
📖 第 1 页 / 共 5 页
字号:
have been added so that circle is a complete class by itself.  It is interesting that one of the 
main benefits from <a href="chapter1.htm#inheritance">inheritance</a> and <a href="chapter1.htm#polymorphism">polymorphism</a> in C++ will be found here.  Careful use 
of <a href="chapter1.htm#inheritance">inheritance</a> will reduce the code size.  The code in a base class that is not changed by 
<a href="chapter1.htm#inheritance">inheritance</a> will be used by all classes inherited from the base.  Therefore, the code in 
move() will not be repeated in the classes inherited from Graph unless there is something 
unique to the class that will not allow use of the base class <a href="chapter1.htm#method">method</a>s.
<pre>
 
	#ifndef RECTANGLE_H
	#define RECTANGLE_H
	#include "defines.h"
	#include "graph.h"
	    
	/* elements and <a href="chapter1.htm#method">method</a>s of the class graph */
	#define RECTANGLE_CLASS\
	             GRAPH_CLASS\
	    void     (* resize)(struct rectangle*,int,int);\
	    int      x1;\
	             y1;

	typedef struct rectangle
	{
	    RECTANGLE_CLASS
	} Rectangle;

	Rectangle* rectangle_(int,int,int,int,int,int); 
	void rectangle__(Rectangle*);

	#endif
</pre>
 
<p>The class Rectangle remains to be implemented.  The basic approach to the 
creation of this class is quite similar to that used with Point and Circle above.  The header 
file is written above, and the <a href="chapter1.htm#implementation_file">implementation file</a> is shown below.  Note here that we have 
created a special function that is equivalent to a private <a href="chapter1.htm#method">method</a> in C++.  This function, 
draw_rectangle() is used by both hide() and show().  There is no reason that this function 
should be called by any part of the program other than by these two <a href="chapter1.htm#method">method</a>s.  Therefore, 
this static function can be seen in the <a href="chapter1.htm#implementation_file">implementation file</a> only and is hidden from the rest 
of the program.  Of course, the only way that hide() and show() can be accessed is 
through the <a href="chapter1.htm#method">method</a> function pointers contained within the instantations of Rectangle 
objects.
<pre>
 
	#include "rectangl.h"
	static draw_rectangle(int,int,int,int); 

	static void hide(Rectangle *this)
	{
		this->visible=FALSE;
		pen_color(this->background);
		draw_rectangle(this->x,this->y,this->x1,this->y1);
	}

	static void show(Rectangle *this)
	{
		this->visible=TRUE;
		pen_color(this->foreground);
		draw_rectangle(this->x,this->y,this->x1,this->y1);
	}

	/* x_new and y_new are the new rectangle sides */
	static void resize(Rectangle *this,int x_new,int y_new)
	{
		Boolean see=this->visible;

		hide(this);
		this->x1=this->x+x_new;
		this->y1=this->y+y_new;
		if(see)
			show(this);
	}

	static move(Rectangle *this,int x_new,y_new)
	{
		int delx,dely;
		
		delx=x_new-this->x;
		dely=y_new-this->y;
		hide(this);
		this->x=x_new;
		this->y=y_new;
		this->x1+=delx;
		this->y1+=dely;
		show(this);
	}

	static draw_rectangle(int x1, int y1,int x2, int y2)
	{
		move_to(x1,y1);  /* start at one corner */
		line_to(x2,y1);  /* and draw a line around */
		line_to(x2,y2);  /* the rectangle */
		line_to(x1,y2);
		line_to(x1,y1);
	}
</pre>
 
<p>	The <a href="chapter1.htm#constructor">constructor</a> and <a href="chapter1.htm#destructor">destructor</a> are shown below.	
<pre>
 
	Rectangle* rectangle_(int x, int y, int x1, int y1, 
				int background, int foreground)
	{
		Graph* temp;
		Rectangle* this;

		temp=graph_(x,y,background,foreground);
		if((this=(Rectangle*) malloc(sizeof(Rectangle)))==NULL)
			error_handler();

		memmove(this,temp,sizeof(Graph));
		graph__(temp);

		this->hide=hide;
		this->show=show;
		this->move=move;
		this->resize=resize;
		this->x1=x1;
		this->y1=y1;
		return this;
	}

	void rectangle__(Rectangle* this)
	{
		hide(this); /* hide before destroying */
		free(this);
	}
</pre>
 
<p>The following test program uses each of the above objects.  Note that the various 
<a href="chapter1.htm#header">header file</a>s are each included in this program.  Within main() the variables foreground and 
background are given values corresponding to white and black respectively.  An instance 
of Point, Circle,and Rectangle is created.  The point is at the center of the screen which is 
also the center of the circle.  The circle has a radius of 80 and the rectangle is placed 
around the circle.  The rectangle, a square in this case, is made one pixel larger than the 
circle in each dimension.  The computer is put into a graphics display mode, and these 
objects are then shown followed by a getch() which will freeze the image on the screen.  
After a key is hit, the rectangle is moved to the right and the circle with its center point is 
moved to the left. Then the image is again frozen until a key is hit.  After a key is hit the 
second time, the rectangle is  resized. 
<pre>
 
	#include &lt;graphics.h&gt;
	#include "point.h"
	#include "circle.h"
	#include "rectangl.h"

	main()
	{
	     int foreground=15,background=0;                                             
	     Point *pt=point_(320,240,background,foreground);
	     Circle *cir=circle_(320,240,80,background,foreground);
	     Rectangle *rect rectangle_(241,321,401,161,background,foreground);
	     
	     setvmode(VGA_16);
	     (*pt->show)(pt);
	     (*cir->show)(cir);
	     (*rect->show)(rect);
	     getch();
	     (*rect->move)(rect,401,321);
	     (*cir->move)(cir,240,240);
	     (*pt->move)(pt,240,240);
	     getch();
	     (*rect->resize)(rect,100,-100);
	     getch();
	     setvmode(DEFAULTMODE);
	}
</pre>
 
<p>	All of the numbers in the above example seem fine with the exception of the y 
value in the rectangle resize call. In that case, the new y value is -100 rather that what 
intuition would say should be 100.  The problem here is that the location of the origin of 
the screen is in the upper left-hand corner rather than  the lower left-hand corner as one 
would have with a graph.  Therefore, all of the increasing y values will move toward the 
bottom of the screen rather than toward the top.  If you want the new rectangle to have its 
locked corner at its lower left-hand corner as these objects assume, you must use negative 
numbers to move toward the top of the screen.

<h2><a name="interface">Toward Better Object Interface</a></h2>

	There are two additional considerations that should be examined now.  First, we 
have made no provisions for the inclusion of an in-line function, and second, there is 
another way for the virtual and inherited functions to be written that will allow a more 
uniform interface with the object <a href="chapter1.htm#method">method</a>s.  Both of these considerations involve the use of 
C macros which is an anathema to most C++ programmers.  One of the most sacred 
considerations that will be found with C++ is the strict type checking that is always in 
force.  On the other hand, C might seem to have relatively strict type checking, but in 
reality, there are areas in which the type checking is completely lax.  The most prominent 
place where type checking falls down in C is through the macro.  A macro is a character 
substitution scheme.  With macros, constants can be defined, but these constants are 
nothing more that character strings that are substituted at the time of compilation.  The 
type of the constant is then  taken in terms of the context of its use in the program.  There 
is no rigidly defined type for any defined constant.  
<p>	Similarly, functions defined by macros are also completely untyped.  As such, the 
programmer can get into trouble very easily when using macro defined functions.  As an 
example, consider the following macro definition for a simple function:
<pre>
 
	#define max(a,b) ((a)>(b)) ? (a) : (b)
</pre>
 
<p>The clear intent of this function is to determine the parameter with the largest value and to 
return this value to the calling program.  So long as both a and b are of the same type, the 
function works well.  The return will be of the same type as both a and b.  Suppose 
however, that the program sent a type int for a and a float for b.  In this case, when a is 
larger than b, an int will be returned to the calling function.  When b is greater that a, max 
will return a float!  We cannot tell for certain the type of the return from a macro, even 
though the calculations that take place will be correct.  The macro is rarely used in C++, 
but it is still a convenient device for C programming.  Just be careful when using macros 
and remember that they can be the source of some difficult problems when you are not 
careful with the types that are being used for parameters to the macro functions.
<p>Let us go back and revisit the program saved in counter2.h and counter2.c  These 
files are listed below for convenience.  
<pre>
 
	#ifndef COUNT_H
	#define COUNT_H

	#include "defines.h"

	#define COUNT  \
	    WORD count;  \
	    void (*increment)(struct cnt *);\
	    WORD (*query)(struct cnt *);


	typedef struct cnt
	{
	    COUNT
	}Count;                                                        

	Count *count_(void);
	void count__(Count *);

	#endif
</pre>
 
<p>The <a href="chapter1.htm#implementation_file">implementation file</a> for this class is shown below.
<pre>
 
	#include "counter2.h"
	#include &lt;stdlib.h&gt;    /* needed for the memory functions */

	static void increment(Count *this)
	{
	    this->count++;
	}

	static WORD query(Count *this)
	{
	    return this->count;
	}

	Count *count_(void)
	{
	    Count *this;
	    
	    this=(Count *)malloc(sizeof(Count));
	    this->count=0;
	    this->increment=increment;
	    this->query=query;
	    return this;
	}

	void count__(Count *this)
	{
	    free(this);
	}
</pre>
 
<p>	We will make a few simple changes in these files that simplify the use of the 
<a href="chapter1.htm#method">method</a>s of the object.  First,

⌨️ 快捷键说明

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