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

📄 manual.txt

📁 AlertDriver c++模块化类库
💻 TXT
📖 第 1 页 / 共 5 页
字号:
*text);
   ...
};  //class Integer
...
void Integer::GetErrorText(const long errorCode, char *text)
{
   switch (errorCode)
   {
      case errIntDivByZero : strcpy(text, "Divide by zero in
Integer object.");
                             break;
      case errIntOverflow  : strcpy(text, "Value too large
for Integer object.");
                             break;
      default              :
AlertableObject::GetErrorText(errorCode, text);
                             break;
   };   //switch statement to determine error text
};   //member function Integer::GetErrorText

To  invoke  the  use  of your strings in your  member  functions,
you  simply  call  the  appropriate  Handle*()  member  function,
passing  the  correct  alert  constant.  As  always,  you  should
call   the   appropriate  Handle*()  member  function  from   the
member   function   where   the  alert  is   first   encountered.
Because   the  Handle*()  member  functions  automatically   call
the  Get*Text()  and Report*() member functions,  a  simple  call
to  the  appropriate Handle*() member function  sets  the  entire
chain of events into motion.

At   first,  this  may  seem  like  a  roundabout  way  of  doing
things,   until  you  realize  the  amount  of  flexibility   and
reusability   that  your  code  gains.  Because  the   Get*Text()
member   functions  are  virtual,  you  can  override   them   in
descendant   classes.  If  you  don't  like  the   text   for   a
specific  alert  code, you can derive a new class  and  return  a
different  string  for  the code, even  if  you  don't  have  the
source  code  for  the  original  class.  The  Get*Text()  member
functions  don't  even  have  to store  the  alert  text  in  the
program;  the  functions can be written  to  retrieve  the  alert
text  from  an  external text file. Using  an  external  file  to
store  the  strings  for  each alert  allows  an  application  to
use  a  minimal  amount  of  program memory  to  store  text.  In
addition,   the  text  file  can  later  be  altered  to   update
existing  alert  text  without  requiring  recompilation  of  the
application.  Coupled  with  the platform-independent  output  of
the     AlertDriver,     these    capabilities     give     every
AlertableObject  maximum  flexibility  in  presenting  alerts  to
the user.

Example   11   demonstrates  how  the  overloaded  "/"   operator
handles errant attempts to divide Integer objects by zero.

Example   11   -   The   overloaded  operator   member   function
Integer::operator   /()   calls   inherited    member    function
HandleError()  whenever  it  detects  an  attempted   divide   by
zero.  Invoking  the  HandleError()  member  function  causes  an
eventual  call  to  the Integer::GetErrorText()  member  function
shown in Example 10.

int Integer::operator / (int aValue)
{
   int result;   //holds the function result

   if (aValue)
      //specified value is not 0
      result = val / aValue;
   else
   {
      HandleError(errIntDivByZero);
      result = INT_MAX;
   }
   return result;
};   //overloaded operator Integer::operator /



Changing & Sharing AlertDrivers

All   programs   linked  with  the  AlertDriver   Class   Library
automatically    gain    access   to   a   default    AlertDriver
referenced   by  the  defaultAlertDriver  pointer   (defined   in
ALERTDRV.H).    This   global   AlertDriver   is    usually    an
interactive,   screen-oriented  driver   which   provides   alert
reporting   capabilities   for  the  software   environment   for
which     the     program    was    targeted.    For     example,
defaultAlertDriver  may  provide text-mode  output  for  a  text-
mode   program,  but  will  use  Windows  dialog  boxes  if   the
program  has  been  compiled  as a Windows  application.  Because
defaultAlertDriver  is  available to  be  called  from  any  part
of   your  application,  even  your  non-object  code  can   call
defaultAlertDriver's   member   functions   (see   Example   12).
Calling   one   of   the  Handle*()  member  functions   of   the
AlertDriver   class  is  equivalent  to  calling   one   of   the
AlertableObject::Report*()  member  functions  (see   the   Class
Library Reference for details).

Example  12  -  Accessing defaultAlertDriver's  member  functions
from  non-object  code.  Calls  made  in  this  way  are  roughly
equivalent  to  the  quick-and-dirty method of  reporting  alerts
from within objects.

#include <alertdrv.h>
...
void main(void)
{
   ...
   //test the defaultAlertDriver without an object
   defaultAlertDriver->HandleInfo(
      "Text from non-object code.");
   ...
};   //function main()

Each  AlertableObject (and derived object)  that  is  created  by
your  program  initially  uses  the  defaultAlertDriver  as   its
AlertDriver.    By    using   this   common   AlertDriver,    the
AlertableObjects  in your program gain all  of  the  benefits  of
platform-independent   error  reporting   with   a   minimum   of
code/data  overhead.  One  AlertDriver  controls  the  alerts  of
all your program's objects.

There  are  times,  however, when you may  want  to  change  this
default   behavior,  particularly  if  the  default   AlertDriver
does  not  provide  the  appropriate  type  of  output  for  your
object.   For  example,  although  the  default  AlertDriver   is
usually  screen-oriented,  your  may  want  your  object  to  log
alerts to a disk file.

You  can  easily  change  the type of AlertDriver  used  by  your
object                by               calling                the
AlertableObject::ChangeLinkedAlertDriver()    member    function.
To  call  this  inherited  member  function,  you  create  a  new
AlertDriver  object,  then pass its address  as  a  parameter  to
the  function.  Because  all  AlertDrivers  should  be  allocated
on  the  heap,  this can usually be accomplished  with  one  line
of  code.  For  example, the following line of code  will  change
the   AlertDriver  for  object  MyObj  to  an  AlertDriver  which
logs alerts to a text file named "myobj.log":

MyObj.ChangeLinkedAlertDriver(new
TextFileAlertDriver("myobj.log", radFREERESOURCE));

(The  radFREERESOURCE  constant  forces  the  TextFileAlertDriver
to  free  (close) the file whenever it is not in  use;  when  the
file  is  closed  (not recording alerts), it can be  accessed  by
other   TextFileAlertDrivers  or  other  applications.  See   the
Class  Library  Reference  for more details  on  controlling  the
TextFileAlertDriver.)

AlertDrivers  allocated  by your application  can  serve  several
AlertableObjects  at  once,  just  as  the  default   AlertDriver
originally  serves  all of the objects in your  program  as  they
are  created.  Example 13 demonstrates how  to  share  one  newly
allocated AlertDriver among two objects.

Example  13  -  Creating  an AlertDriver object  and  sharing  it
among  multiple  objects. In this case,  both  objects  will  log
their  alerts  to  the  same text file.   Remember,  AlertDrivers
which   you   create  within  your  program  should   always   be
allocated on the heap.

...
AlertDriver *pAlertDriver;
Integer a, b;
...
/*log a and b alerts to the same text file -
  other AlertableObjects continue to use
  defaultAlertDriver*/
pAlertDriver =
   new TextFileAlertDriver("myobjs.log",
                           radFREERESOURCE);
a.ChangeLinkedAlertDriver(pAlertDriver);
b.ChangeLinkedAlertDriver(pAlertDriver);
...

To  completely  remove  (not  replace)  the  AlertDriver  for  an
AlertableObject,          call          member           function
ChangeLinkedAlertDriver()  with  a  parameter  of   NULL;   doing
this   will   remove   all   alerting   capabilities   for    the
AlertableObject.

The  AlertDriver  Class  Library  defines  the  standard  classes
StdAlertDriver   and   TextFileAlertDriver   for   all   software
platforms  and  environments. StdAlertDriver  uses  the  standard
C++  iostreams  cin,  cout, and cerr  to  report  alerts  to  the
user   while  TextFileAlertDriver  logs  alert  text  to  a  file
which    is    specified    in   its   constructor.    Additional
AlertDriver   classes   may   be  defined   for   your   specific
software       environment       (for       example,        class
TurboVisionAlertDriver   is   defined    for    programs    using
Borland's  Turbo  Vision class library). See  the  Class  Library
Reference   chapter   for  full  details   on   the   AlertDriver
classes   which   are   available  in  your   specific   software
environment.

Experienced  programmers  know that one  of  the  toughest  parts
of  debugging  a  program  is  finding  heap  allocation  errors.
Because  all  AlertDrivers are allocated  on  the  heap  and  may
be   shared   among  multiple  AlertableObjects,   you   may   be
wondering  if  there  is  an  easy  way  to  determine  when   an
AlertDriver  is  no  longer being used and when  it  is  safe  to
deallocate  an  AlertDriver. The answer  is  simple:   you  don't
have   to   worry  about  deallocating  any  AlertDrivers,   even
those   which   you  allocate!  The  AlertDriver  Class   Library
handles it all for you!

Each   AlertDriver   contains  a   count   of   the   number   of
AlertableObjects   using   its   services.    This    count    is
incremented  each  time  an  AlertDriver  is  "attached"  to   an
AlertableObject.  An  AlertableObject  is  "detached"   from   an
AlertDriver   whenever   the  AlertableObject   is   deallocated,
goes  out  of  scope,  or is attached to a different  AlertDriver
object   through   member   function   ChangeLinkedAlertDriver();
each  time  this  happens, the attached  AlertDriver's  count  is
decremented.  When  the count reaches zero  (the  AlertDriver  is
no   longer  being  used  by  any  object),  the  AlertDriver  is
automatically  shutdown  and  deallocated.  What  this  means  to
you   as   a  programmer  is  that  you  can  allocate  as   many
AlertDrivers  of  as  many  different classes  as  necessary  and
attach  them  to  as  many AlertableObjects as  you  desire  with
the   understanding  that  each  of  the  AlertDrivers  will   be
deallocated as soon as it is no longer being used.


Linking AlertDrivers

Although  you  can  change  the  AlertDriver  used  for  each  of
your  objects  at  any  time, this still may  not  give  you  the
level  of  flexibility  you need. After  all,  it's  nice  to  be
able   to   switch  between  screen-based  alerting  and  logging
those  alerts  to  a  disk file, but what if  you  wanted  to  do
both  at  the  same  time?  With the AlertDriver  Class  Library,
you  can  attach  several  AlertDrivers  together  in  series  so
that  the  same  alerts  are  reported  in  multiple  ways.  This
process is known as "linking" the AlertDrivers.

To   link   one  AlertDriver  to  another,  you  must  call   the
ChangeLinkedAlertDriver()   member   function   of   the    first
AlertDriver  object.  (The first AlertDriver  object  is  defined
as  the  AlertDriver  which is attached  to  an  AlertableObject,
the   remaining   AlertDrivers   are   each   attached   to   the
previously   linked  AlertDriver.  In  effect,  the  AlertDrivers
form  a  linked  list,  often  referred  to  as  a  "chain.")   A
common  use  of  linking AlertDrivers is  to  provide  disk  file
logging   in   addition   to  screen  alerting   by   linking   a
TextFileAlertDriver   to   an   AlertableObject's    AlertDriver.
This    can    be    most    easily    accomplished    if     the
AlertableObject's   AlertDriver  is   the   default   AlertDriver
(see Example 14).

Example  14  -  By linking a TextFileAlertDriver to  the  default
AlertDriver,  all  objects  using the  default  AlertDriver  will
report  their  alerts  to  both  the  screen  and  a  disk   file
(assuming  that  the default AlertDriver reports  alerts  to  the
screen).

...
//attach a text file AlertDriver to the default driver
defaultAlertDriver->ChangeLinkedAlertDriver(
   new TextFileAlertDriver("adtest.log", radFREERESOURCE));
...

It    is    important    to    note   that    when    you    call
AlertableObject::ChangeLinkedAlertDriver()                     or
AlertDriver::ChangeLinkedAlertDriver(),   you   are   effectively
replacing   all   AlertDrivers   which   are   linked   to    the
object/driver   with   the   AlertDriver   you    specify.    For
illustration,  assume  that  prior  to  calling   the   code   in

⌨️ 快捷键说明

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