📄 chapter1.htm
字号:
talk of objects in real life, we generally refer to things that exist in our daily experiences.
A laptop computer, a dog, an automobile, a light switch, a washing machine, etc., might
be cited as examples of objects we see daily. Webster defines an object as a thing "that
can be seen or touched," or "thing that occupies space." We are going to extend these
ideas a bit. The idea of an object indeed encompasses the above, but it will also include
programming things that will exist in a program but never in the real world. Examples of
such items include things like semaphores, linked lists, stacks, and other software entities
that can be thought of as things or objects.
<p>
Most objects encountered in real life have some attributes. The attributes of an
object are those things that distinguish an object from another similar object, they might
describe the state of the object, they may identify details of the object like its color, or they
might describe an internal set-up of the object such as the program that controls
temperature vs. time found in a sophisticated thermostat. Attributes are characteristics or
qualities of a thing. Some attributes can be changed with great effort like the color of an
automobile. Others can be changed, but access to make the changes are usually through a
special route contained within the object. A perfect example here is that the engine of an
automobile can be started with a key and then only when the transmission is in Park or
Drive. Of course, the states Park or Drive are other attributes of an automobile, so you
can see that attributes can interact with each other. However, attributes cannot be
changed helter skelter from outside of the object. It is inconceivable that an outside action
should change the transmission state from Drive to Park. This action can be accomplished
only by the shift of a lever that is a part of the automobile. Attributes are hidden in a sense
from the outside, and can be accessed only through designated actions contained within
the object itself.
<p>
The above discussion is about an object. An object usually can be thought of being
a specific instance of a class. To continue the idea of an automobile, we might have a
class that includes all automobiles. Drawn from this class is any individual automobile; for
example, Mary's Ford. This particular automobile is red, it has four doors, it is air
conditioned, it has cruise control, with a special sound system for entertainment, and it has
a V6 engine. This car is unique. There are probably other automobiles with exactly the
same attributes, but they are not Mary's car. Mary's car is an instance of the class
automobile, and no other instance of this class can be Mary's car.
<p>
We have seen two important components of a class. The first is the attribute and
the second will be called the method. Classes will have attributes that provide the
uniqueness of different objects based on the class. These attributes can be given values at
the time the object is created or at various times during the life of the class. For example,
the automobile is painted red during its manufacture, and it is difficult to change its color.
On the other hand, the state of the engine -- ON or OFF -- is changed during the operation
of the automobile. Attributes are internal to the object and cannot be altered from the
outside of the object without either some major effort or through routes from the object
surface to the attribute's domain within the object. The class is the repository of the
attributes: each class will contain a list of attributes that and each object derived from the
class can have. Each object will have its own set of unique attributes drawn from those
available to the class. The objects attributes are limited to those of the class from which it
is derived.
<p>
It is undesirable for an attribute to be changed from outside of the object.
Essentially all attributes, even though they are variable, are hidden from the outside world.
They are private to the class or object. If an attribute is a variable, it is usually accessible
for change or other access through special functions. The engine is turned on and off with
the key, the radio is controlled by the operator, the gear shift is controlled by the driver,
etc. Access to these things is through a set of controls designed specifically to deal with
the various attributes. In the software world, these access mechanisms are called
methods.
<p>
Leaving the real-world analogy, we can look into objects and classes as software
entities. The methods of a class are a set of functions that allow access into the private
recesses of an object. Methods are a part of the class. Attributes are usually private and
the only way that you may deal with these attributes is through a series of methods that
are necessarily public. Here public means that these methods can be seen and used by
anybody. The radio controls in your car, its gear shift, the horn button are example public
methods that control attributes of the automobile. Methods usually cause something to
happen. As operators, we usually do not care how the method works, only that when
used the object behaves in an expected manner.
<p>
A class is a type. This type has the same status as any other type in the language.
An instance of such a type is an object. Therefore, the class is found only once in a
program and as many instances of the class, or objects, as needed can be created through
the use of define statements in the program.
<p>
Usually attributes are private and methods are public. Of course, we can have
public attributes and private methods. The private method is a function accessed only by
the public methods and a public attribute can be seen an accessed from anywhere in a
program. The public attribute is not often used. The block diagram shown in Figure 1
shows the layout of a class. Note that there is a heavy line around the innermost part of
the class. A program using objects of this class should not be able to penetrate this heavy
line except through the methods that are shown entering the private portion of the class.
Any box that penetrates the private portion of the class has full access to all private data.
The public methods are shown as method 1, method 2 and method 3. There are several
special methods that can be associated with a class. Two, the constructor and destructor,
are needed to create an object and to destroy an instance of an object when needed. In an
OOP language like C++, the constructor will be executed automatically whenever a define
statement causes the creation of a new instance of an object. The destructor is executed
when the object goes out of scope. We will be using C only, so execution of both
constructor and destructor to create and destroy an object when needed will be the
responsibility of the program. Usually, objects are created and destroyed when need.
Such an approach implies dynamic allocation of any needed memory to the objects during
execution of the constructor. In a system where memory is limited, it will be necessary to
allocate memory and free it when the object is no longer needed to avoid overuse of the
available system memory.
<p>
<p>
<p><img align=middle src="fig1-1.jpg">
<h3>Figure 1.1 A block diagram of a class</h3>
<p>
<p>
Another special type of method is called a virtual method. Such a method is used
to implement polymorphism, and it will be shown in detail in Chapter 2. Finally, a friend
function is a function that has access to the private parts of an object, but it is not a
method of the class. As such, a friend is a function that, by design, can get around the
restrictions implied by the private access label attached to the attributes.
<p>
Another characteristic of an object/class system is that of inheritance. The idea of
inheritance is simple. Any class can use another class in its own creation. When one class,
the derived class, inherits the properties of another class, the base class, the derived class
will have access to all of the base class attributes and methods that are have a protected
access rather than private.
<p>
Why should we be so concerned about the access privileges of the members of a
class? In looking at the class automobile above, we have seen that there are attributes that
should be set by the operator, and that these attributes should not be accessible to outside
entities. The transmission setting, PRNDL, must be available to the driver only. If an
outside force could alter the transmission setting while the automobile is being driven,
there is no ending to the mischief that could be played on unsuspecting drivers. It is the
same problem in programming. Attributes are the things that make an object unique.
Uncontrolled access to these attributes will open the program using the object to the same
types of problems that drivers might have when they do not have complete control over
their vehicle. Methods are created to perform all access needed on the attributes, and the
design of the methods should be concerned with all aspects of the attribute. It makes
sense to reject attributes that are not in a correct range; those that are of the wrong type;
attributes that should not be changed at all. It is the method's responsibility to filter these
types of errors and keep the attributes of the object proper. If the attributes could be
accessed from any part of the program without the help of the methods, a situation will
arise where a part of the program will alter an attribute value and it will be wrong. By
locking the attributes inside of the object and not allowing access except through method
calls, we will avoid problems that can occur through unintended modifications of the
attributes.
<p>
The class, that defines a type, have the representative components shown in Figure
1.1. We will see classes that contain no attributes, or no methods, some that contain no
constructor or destructor. A class is the code that pulls together all of the components of
an object and holds them together in a form that can be used easily by a program. In our
code, a class will consist of two parts. The header file contains needed definitions, the
structure that will be turned into a type usable throughout the program with a typedef
keyword, function prototypes of methods needed by objects of the class, function
prototypes of the constructor and destructor, and any macro defined functions needed by
the class. The structure at this point in the program is a declaration statement that
identifies the nature of the structure to the compiler, but no instance of the structure yet
exists. Header files do not contain executable code. This header file must be included
with any code that is to make use of objects of this class.
<p>
Associated with the header file is a definition or implementation file. This file
contains all of the code for the various functions and methods needed to implement the
class. Almost always, there will be the constructor and the destructor. The constructor is
a function that creates an instance of the class which is called an object. To create this
instance, the constructor allocates memory to hold a copy of the object and then it copies
its own arguments into the variable members of the structure. A pointer to this structure
is returned to the calling program. Access to the particular object is through the pointer
returned by the constructor. Most of the time, the destructor simply executes the free()
function to return the memory used by an object to the free memory pool.
<p>
Member functions, or methods, show up in several different ways. The easiest
way to handle member functions is to treat them as any other functions found in the
program. Their code will be contained in the implementation file, and this file will be
compiled and linked into the program. These functions will then be available to the whole
program. In other instances, it will be desirable to provide access to the methods through
pointers to these functions that are placed in the structure that defines the class. This
approach requires a single level of indirection to access the class methods. Other instances
when these pointers will be collected into a separate structure will be seen. Access to
these methods will require two levels of indirection. There are other reasons that function
pointer tables will be created to aid in run-time binding.
<p>
Many simple examples of the creation of classes and objects will be shown in
Chapter 2. These examples will demonstrate implementation of inheritance,
polymorphism, and other important coding techniques needed for object oriented
programming in C.
<p>
A class is a most reusable piece of code. A properly written and debugged
hierarchy of classes can form the basis onto which any modifications of the existing
classes can be easily made. These modifications are safe and effective if the code is
written in a language that embodies all of the main three concepts of object oriented
programming. Modification to existing classes are made through inheritance. An
inherited class has access to attributes and methods of the base class. Therefore, those
things about a class that are unmodified by inheritance will continue to function as
expected. Of course, newly added features will suffer all of the problems of any new
code, but the old code will remain unchanged.
<p>
The problem of attribute hiding cannot be avoided when writing object oriented
code in C. This unfortunate circumstance does open object oriented code written in C to
problems that would not exist if the attributes could be properly hidden. Therefore, it
must be stated, and stated, and restated, that all program accesses to any object attribute
must be only through the class methods. Any programmer who violates this rule opens
the whole concept to trouble. In fact, one of the reasons that it was decided to
concentrate on the idea of reusable components rather than object oriented programming
is this inability of C to hide attributes within a structure.
<p>
The idea of a component is easy to understand now. Most of the programs we
write for embedded systems consists of typical procedural programs. The goal here is to
alter the program design approach. Like a circuit, a program will be treated as a
collection of components that are connected together with a program. Each component
can be created by the programmer, by other programmers in the programming team or
perhaps purchased from an outside vendor. The components will be standard program
items like semaphores, lists in their many forms, or other data structure items. A major
new addition to the list of components will be added here, the computer peripheral. All of
these items could well be created as classes in an object oriented language, but here we
will create them in C and treat them as components with which we can build a program.
<p>
The abstraction of any high level language hides the computer from the
programmer. Usually such things as registers and control bits in the registers are hidden
from the programmer. This abstraction makes it easier for the language standard to define
a language and avoid any worry about the computer being programmed. This abstraction
works for essentially all main-line programs. This abstraction fails us terribly when we
must work with peripherals that usually contain memory mapped registers and
input/output devices that must be accessed by the computer. The concept of a component
supports our programming needs very well here. C provides the means to access and deal
with the memory mapped items found with the peripherals. If the peripheral is pulled into
a component, it will be possible to contain all accesses to the peripheral control logic
within the component, and the program will be able to treat the peripheral as it would any
other logical device in the system. The peripheral devices can be controlled from a
program using components without our breaking the abstraction of the high level language
because the component will hide all of the details of peripheral interface with the program
from the main program.
<hr>
<p>
<a href="copyrite.htm#copyright">Copyright</a>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -