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

📄 manual.txt

📁 AlertDriver c++模块化类库
💻 TXT
📖 第 1 页 / 共 5 页
字号:
platforms  and/or  hardware  devices  and  linked  into  programs
written  for  the  AlertDriver Class Library with  no  change  to
the   underlying  application  logic  or  AlertableObject  source
code.

With  the  concepts  described to this point and  their  inherent
programming   power   and  flexibility,  most   class   libraries
would   stop   here.  However,  the  AlertDriver  Class   Library
provides   solutions  to  even  more  programming  problems.   An
AlertDriver  object  itself  can  reference  another  AlertDriver
object,  effectively  chaining,  or  linking,  the  AlertDrivers.
By   linking   the  AlertDrivers  for  an  AlertableObject,   the
AlertableObject  can  report  a single  error  in  multiple  ways
(for  example,  an  error  can  be reported  to  the  screen  and
logged  in  a  disk  file).  AlertDrivers  can  be  attached  and
detached  from  AlertableObjects in  any  combination  at  either
compile-time  or  run-time  for maximum  program  efficiency  and
flexibility.

Each  AlertDriver  can  also  have  its  actions  controlled   at
either   compile-time  or  run-time  via  a  set  of   processing
flags.   Error-handling,   for  example,   can   be   temporarily
turned  on  or  off  for each AlertDriver  without  the  need  to
disconnect   or  destroy  the  driver.  Other  useful  processing
flags,  which  allow  a tremendous amount  of  control  over  the
AlertDriver during run-time, are also available.

The  AlertDriver  library also mirrors the  concepts  of  client-
server   technology:   each  AlertableObject  can  be  considered
to   be   a  client,  each  AlertDriver  a  server.  The   client
initiates  an  action  (i.e.:   report  an  error  message)   and
each  server  has  the ability to perform that  action.  Multiple
clients  can  be  attached to a single server and  a  client  may
be served by multiple servers.

The  ability  to  connect several AlertableObjects  to  the  same
AlertDriver   allows   applications  to   retain   all   of   the
advantages  previously  discussed  while  minimizing  the  amount
of  memory  overhead  needed  to implement  those  features.  For
example,   in   a   spreadsheet  application,  each   spreadsheet
object  could  can  be derived from an AlertableObject.  If  each
cell   required  its  own  AlertDriver,  then  available   memory
would  decrease  rapidly  as the spreadsheet  grew.  However,  by
allowing  each  cell  to share a common AlertDriver,  the  memory
needed  to  implement  AlertDriver  processing  is  held   to   a
small,   fixed   amount  (the  amount  needed  to  allocate   the
common   AlertDriver).   Since  all  cells   in   a   spreadsheet
normally   report   errors  in  the  same  manner   anyway,   the
unnecessary  allocation  of  duplicate  AlertDriver  objects   is
avoided.

In   the   next   chapter,  we  will  discuss  how  easily   your
programs  can  use  the  AlertDriver Class  Library  as  we  step
through a tutorial.



Chapter 3           An AlertDriver Tutorial
                    

Creating New Objects

To  use  the  AlertDriver Class Library,  you  must  include  the
following line in your source code file:

#include <alertobj.h>

The  ALERTOBJ.H  header  file contains the  declaration  for  the
AlertableObject    class.    (The    implementation    of     the
AlertableObject  class  is supplied in  a  separate  object  code
file   which   is  platform-dependent  -  see  the  Compiling   &
Linking  chapter  for  details  on  compiling  and  linking  your
code with the supported compilers/platforms.)

To  create  classes  of your own, you simply  derive  your  class
from  AlertableObject  using  public inheritance.  (For  purposes
of  demonstration,  we  will present  a  simple,  and  admittedly
contrived,   sample  class  named  Integer,   which   by   itself
doesn't  really  do  anything  useful,  but  will  allow  us   to
demonstrate   the  proper  syntax  and  implementation   of   the
AlertDriver   library   concepts  -  sample  platform-independent
source   code   implementing  Integer  is   included   with   the
AlertDriver   Class  Library.)  Your  class  will   automatically
inherit   the   member  functions  and  data  of  AlertableObject
(see Example 7).

Example  7  -  To  derive  your own classes,  derive  your  class
from AlertableObject using public inheritance.

class Integer : public AlertableObject
{
   ...
   /*declare class-specific member
     functions and data members here*/
   ...
};   //class Integer


Programmer-Defined Codes, Detection, & Reporting

Once    you    have   inherited   the   capabilities    of    the
AlertableObject   class,   you   will   want   to   access   that
functionality   from  your  member  functions.  There   are   two
basic  ways  of  using  the AlertableObject member  functions  to
alert  the  user  of  program conditions:  the  "quick-and-dirty"
method and the "preferred" method.

The Quick-And-Dirty Reporting Method
The   quick-and-dirty  method  of  using  the  AlertDriver  Class
Library   is   usually   used  during  program   testing   and/or
debugging.  Using  this  method, your  object  passes  a  literal
string  to  the  attached AlertDriver to alert the  user  of  the
program's  condition.  The  quick-and-dirty  method  retains  the
platform-independent   output  of  the   AlertDriver,   but   the
messages  themselves  are hard-coded into  the  program,  clearly
not  the  most  elegant solution. However,  this  method  is  the
quickest  and  easiest  to  use  for  quickly  getting   a   test
program  to  work  or  for  porting  existing  programs  to   the
AlertDriver  Class  Library. Programs written  using  the  quick-
and-dirty   method  can  easily  be  ported  to   the   preferred
method later.

To  use  the  quick-and-dirty method,  your  code  calls  one  of
the   Report*()   member   functions.   There   are   four   such
functions   (see   the  Class  Library  Reference   chapter   for
details),   one   for   each  type  of   alert:    ReportError(),
ReportInfo(),      ReportMessage(),     and      ReportWarning().
(ClearMessage(),  a  related function used  in  conjunction  with
member   function  ReportMessage(),  clears  the   last   message
posted.)

Example  8  shows  how  the  code  in  Integer::TestAlertDriver()
makes  calls  to  these  functions, passing  literal  strings  to
each;  the  AlertDriver  for  the Integer  object  reports  those
strings to the appropriate output device/platform.

Example  8  -  Calling  the Report*() member functions  inherited
from   AlertableObject.   Each  of  these   inherited   functions
passes the string along to the object's AlertDriver.

void Integer::TestAlertDriver(void)
{
   ...
   //test literal strings
   ReportMessage("Literal:  This is a message string.");
   ReportError("Literal:  This is an error string.");
   ReportWarning("Literal:  This is a warning string.",
adsYES);
   ClearMessage();
};   //member function Integer::TestAlertDriver

One  final  note  on  reporting alerts:  the  Report*()  function
should  always  be  called  from the member  function  where  the
alert   is   first  encountered  or  generated.  By  consistently
following  this  suggestion, the code  which  calls  your  member
functions  can  be  written to assume that any  alerts  occurring
within  your  member  functions have  already  been  reported  by
the time the function returns.


The Preferred Reporting Method

The  preferred  method of reporting alerts requires  a  bit  more
work  than  the  quick-and-dirty  method,  but  results  in  code
which  is  infinitely  more  reusable  and  flexible.  We  highly
suggest   that  any  new  programs  and/or  objects  be   written
using   the   preferred  method  of  alert  reporting,   as   the
preferred   method   results  in  programs   which   are   better
structured than programs using the quick-and-dirty method.

Before  we  explain  how  to use the preferred  method,  we  must
first  discuss  the  concepts of using  programmer-defined  codes
for   the  alerts.  Each  unique  alert  for  a  class   can   be
assigned  a  unique  constant  value  for  that  type  of   alert
within   the  class.  For  example,  the  error  codes  for   the
Integer  object  are numbered starting at one  (1).  Each  unique
warning   alert  for  the  Integer  object  is  also  represented
with  a  code,  with  the  first warning also  being  number  one
(1).  The  fact  that both alerts have a code  numbered  one  (1)
does  not  cause a conflict - each type of code is  used  in  its
own   context.   Using  constants  (or  #defines)  to   represent
these  codes  in  your  program will  help  both  you  and  other
programmers    to   identify   the   different   contexts    when
reviewing  your  code  (see  Example  9).  While  you   may   use
negative  numbers  as  alert  code constants,  do  not  use  zero
(0)  as  an  identifier for an alert code - zero  is  pre-defined
by  the  AlertDriver Class Library for each  alert  type  as  the
constants  errOK,  infoOK, msgOK, and  warnOK.  Alert  codes  are
represented by long integers.

Example  9  -  Define constants to uniquely identify  each  alert
within  a  class. Each constant for a particular  type  of  alert
within   a  class  may  have  the  same  value  as  the  constant
identifier  of  another  alert  type  in  the  same  class.  Each
constant  may  also  be  equal to constants  of  the  same  alert
type in other classes.

...
//define alert constants for class Integer
const long errIntDivByZero = 1;
const long errIntOverflow  = 2;
const long infoIntConstruct = 1;
const long msgIntDestruct = 1;
const long warnIntChange = 1;
   /*legal - different types of alerts*/
...
//define alert constants for class DiskFile
const long errDiskFileNotFound = 1;   //legal
const long errDiskFileDiskFull = 1;
   /*illegal - same error code (1) defined
     twice for same class*/
...

Because  errors  are  the  most serious  types  of  alerts,  they
should  be  returned  from  member functions  whenever  possible.
This  means  each member function should return  the  error  code
of  any  error  generated  within that function,  or  return  the
error  code  returned  by  functions it  calls.  By  adhering  to
this  principle,  the  program module  which  calls  your  member
functions  will  always  receive  an  error  code  denoting   the
first  error  encountered  during  execution  of  your  function.
Of  course,  your  functions should return  errOK  if  no  errors
occur.

The    use    of    programmer-defined   alert   codes    figures
prominently  in  the  preferred  method  of  alert  presentation.
Rather  than  call  the Report*() member functions,  your  member
functions   call   the  inherited  Handle*()  member   functions.
Each  Handle*()  member  function  corresponds  to  one  of   the
Report*()   member  functions;  the  Handle*()  member  functions
are:     HandleError(),   HandleInfo(),   HandleMessage(),    and
HandleWarning().

Each  of  the Handle*() functions is passed an alert  code  as  a
parameter.  This  alert  code  is  then  passed  to  one  of  the
Get*Text()  member  functions, converted to text,  and  the  text
is   passed  to  one  of  the  Report*()  functions.  Of  course,
there  are  four  Get*Text()  member functions:   GetErrorText(),
GetInfoText(), GetMessageText(), and GetWarningText().
To  use  the  preferred  method of  alerting,  your  object  must
declare  the  appropriate alert constants for  alerts  which  can
be   generated   within  your  object.  You  then  override   the
Get*Text()  functions  to  convert those  constants  to  strings.
In   a   well-developed  class  hierarchy,  if  your   Get*Text()
function  receives  an alert constant which  it  cannot  convert,
it  should  call  the  overridden  Get*Text()  function,  as  the
constant  may  represent  an  alert  which  was  defined   in   a
parent  class.  The  original  Get*Text()  member  functions   in
AlertableObject  produce  generic  messages  (i.e.:   "Error  422
encountered.")   for  unrecognized  alert   codes.   Example   10
shows   the   implementation   of   the   GetErrorText()   member
function for the Integer class.

Example    10   -   Implementation   of   Integer::GetErrorText()
member    function.   Notice   how   error   codes   which    are
unrecognized  by  this class are passed back  to  the  overridden
function.

...
//define error constants for class Integer
const long errIntDivByZero = 1;
const long errIntOverflow  = 2;
...
class Integer : public AlertableObject
{
   ...
   public:
      virtual void GetErrorText(const long errorCode, char

⌨️ 快捷键说明

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