home *** CD-ROM | disk | FTP | other *** search
- #ifndef APPObject_H
- #define APPObject_H
- /******************************************************************************
- **
- ** C++ Class Library for the Amiga© system software.
- **
- ** Copyright (C) 1994 by Armin Vogt ** EMail: armin@uni-paderborn.de
- ** All Rights Reserved.
- **
- ** $VER: apphome:APlusPlus/environment/APPObject.h 1.04 (04.05.94) $
- **
- ******************************************************************************/
-
- extern "C" {
- #include <exec/types.h>
- #include <stdlib.h>
- }
- #include <iostream.h>
- #include <APlusPlus/environment/Classes.h>
-
- #define APPOBJECT_INVALID 0
-
- #ifndef abs
- #define abs(x) ((x)<0?-(x):(x))
- #endif
-
- #ifndef max
- #define max(x,y) ((x)>(y)?(x):(y))
- #endif
-
- #ifndef min
- #define min(x,y) ((x)<=(y)?(x):(y))
- #endif
-
- /******************************************************************************************
- » APPObject class «
-
- Always inherit APPObject virtually!
- See for a tutorial below.
-
- ******************************************************************************************/
-
- class APPObject
- {
- protected:
- long _status;
-
- APPObject() { _status = APPOBJECT_INVALID; }
- virtual ~APPObject() { _status = APPOBJECT_INVALID; }
- void setError(LONG code) { _status = -abs(code); }
- void setID(LONG id) { _status = abs(id); }
-
- public:
- BOOL Ok() { return (_status > 0); } // object' methods are allowed to be invoked only when TRUE.
-
- ULONG error() { return _status < 0 ? -_status : 0; }
- // returns the error number specific for the failed class constructor or 0 if no error ocurred
- ULONG ID() { return _status > 0 ? _status : 0; } // returns the class ID if the object is valid
- LONG status() { return _status; }
- BOOL isClass(LONG id) { return id==_status; } // check for class membership
- };
-
- // check with APPOK(object) if object points to an object and if this object is Ok
- // On uncertainties wether to invoke a method on an object is safe check with APPOK(object).
- #define APPOK(obj) (obj!=NULL && obj->Ok())
-
-
- #define CHECK(obj) if((obj->status<=0) cerr<<"APPObject: invalid in "<<__FILE__<<" at "<<__LINE__<<endl;
-
- // set error code within constructors.
- #define _ierror(code) { setError(code); cerr<<#code<<"//"; }
-
- #define BUGOUT __FILE__<<":"<<__LINE__<<endl
- /****************************************************************************************/
- /* ostreams that should only be compiled while debugging can be enclosed with _dout( ) */
-
- #ifdef DEBUG
- #define _dout(msg) { cerr << msg; }
- #else
- #define _dout(msg) {;}
- #endif
-
- /*****************************************************************************************/
- /* Some standard error types following: */
-
- #define OUT_OF_MEMORY 103
-
-
- /*****************************************************************************************
- » APPObject class «
-
- This is a virtual base class for all APlusPlus classes. It is used to detect constructor failures
- within the inheritance path of an object. Therefore each constructor of a derived class
- should check for the proper initialisation of its super classes and in case of failure
- should not allocate any resources but let the user see the occured error.
- The class user who creates an object should test it for valid with obj->Ok().
-
- myProcedure( )
- {
- DerivedObject *obj = new DerivedObject( );
-
- if (obj) // check for memory allocation failure
- {
- if (obj->Ok()) // check validity of the created object
- {
- .... // work on the object
- }
- else
- {
- _dout(cerr << "Initialisation error occured: " << obj->IError() << endl;)
- delete obj; // free the memory allocated for the object data
- }
- }
- }
-
- Class implementors may check the base class validity within their constructor:
-
- class MyClass : private InheritedClass, virtual public APPObject
- {
- public:
- MyClass( )
- {
- if (Ok()) // has an error already occured ?
- {
- // at this point the object has the class ID of the last class in the
- // inheritance list.
- if (initialise( )==FALSE) // class initialisation
- {
- #define MYCLASS_SOMETHING_FAILED (MY_CLASS+1)
- _ierror(MYCLASS_SOMETHING_FAILED);
- // set the error variable to a value and
- // print the error string "MYCLASS_SOMETHING_FAILED" to stderr
- }
- else setID(MY_CLASS);
- }
- else // initialise only for SAFE destruction, no resource allocation
- {
- }
- }
- }
-
- And add your class to the APlusPlus classes list with its personal class ID:
-
- ADD IN FILE: APlusPlus/environment/Classes.h
-
- #define MY_CLASS xxx
-
- *****************************************************************************************/
- #endif
-