_INSTANTIATING CODE PATTERNS_ by Fred Wild Listing One object PetOwner Name : string ; Pet : ptr_to Pet [is_owner] ; Vet : ptr_to Veterinarian [is_shared] ; end ; object Veterinarian Name : string ; StreetAddress : string ; Town : string ; Phone : string ; end ; object Pet Name : string ; KindOfPet : string ; end ; foreign string [use_ref] ; Listing Two # Create the header file ... # :$$NEWFILE .hxx : :#ifndef _H :#define _H : :// Forward references for each class : .EAch_obj :class ; .ENd : :$$EXECMODULE emit_class_decls : :#endif : # Create the body file ... # :$$NEWFILE .cxx : :#include ".hxx" : :$$EXECMODULE emit_class_bodies : ################################################################### # Module to emit class declarations # .MOdule emit_class_decls .EAch_obj : :// :// Class -------------------------------- :// : :class \ :: \ .EAch_parent :\ :, : .ENd :{ :$$EXECMODULE emit_member_variables : : public: : : (); : (const & obj); : *makeCopy() const ; : virtual ~(); : : &operator=(const &rhs) ; : :$$EXECMODULE emit_attr_access_ftn_decls : :} ; .ENd .ENd ################################################################### # Modules to emit class member variable declarations # .MOdule emit_member_variables .EAch_attr : <30> m_ ; : <30> *m_ ; .ENd .ENd ################################################################### # Module to emit attribute access function declarations # .MOdule emit_attr_access_ftn_decls .EAch_attr :$$EXECMODULE emit_get_decl :$$EXECMODULE emit_set_decl : .ENd .ENd ################################################################### # Module to emit get functions for an attribute # .MOdule emit_get_decl : <35>Get () const ; : const & <35>Get () const; : const * <35>Get () const; .ENd ################################################################### # Module to emit set functions for an attribute # .MOdule emit_set_decl : void <35>Set(const val); : void <35>Set(const & val); : void <35>Set( *val) ; : void <35>Clear () ; .ENd ################################################################### # Module to emit the bodies of member functions for each class # .MOdule emit_class_bodies .EAch_obj : :////////////////////////////////////////////////////////// :// class :$$EXECMODULE emit_class_default_ctor :$$EXECMODULE emit_class_copy_ctor :$$EXECMODULE emit_class_destructor :$$EXECMODULE emit_assignment_op_body :$$EXECMODULE emit_get_and_set_ftn_bodies .ENd .ENd ################################################################### # Module to create a class' default constructor # .MOdule emit_class_default_ctor : :::() :{ .EAch_attr : m_ = NULL; : m_ = ; .ENd :} .ENd ################################################################### # Module to create a class' copy ctor and 'makeCopy' function # .MOdule emit_class_copy_ctor : :::(const & obj) : : \ .EAch_parent :(obj)\ :, : \ : .ENd :{ .EAch_attr : m_ = obj.m_; : m_ = obj.m_; : m_ = obj.m_->makeCopy(); .ENd :} : : *::makeCopy() const :{ : return new (*this); :} .ENd ################################################################### # Module to create a class' destructor # .MOdule emit_class_destructor : :::~() :{ .EAch_attr : delete m_ ; .ENd :} .ENd ################################################################### # Module to create a class' assignment operator # .MOdule emit_assignment_op_body : : & :::operator=(const &rhs) :{ : if (this == &rhs) return *this ; : // No changes if assignment to self : .EAch_parent : (( &) (*this)) = rhs ; : // Assign base class members of .ENd .EAch_attr : m_ = rhs.m_; : m_ = rhs.m_; : m_ = rhs.m_->makeCopy(); .ENd : : return *this ; :} .ENd ################################################################### # Module to create class member functions that access single valued member vars # .MOdule emit_get_and_set_ftn_bodies .EAch_attr :$$EXECMODULE emit_get_ftn_body :$$EXECMODULE emit_set_and_clear_ftn_bodies .ENd .ENd ################################################################### # Module to create a 'Get' function body for accessing an attribute # .MOdule emit_get_ftn_body : Get () const :const & Get () const :const * Get () const :{ : return m_ ; :} .ENd ################################################################### # Module to create a 'Set' and 'Clear' function bodies # .MOdule emit_set_and_clear_ftn_bodies :void Set (const val) :void Set (const & val) :void Set ( *val) :{ : = val ; : if ( != NULL) delete ; : = val ; :} : : :void Clear () :{ : if ( != NULL) delete ; : = NULL ; :} .ENd .ENd Listing Three #ifndef pets_H #define pets_H // Forward references for each class class PetOwner ; class Veterinarian ; class Pet ; // Class PetOwner -------------------------------- class PetOwner { string m_Name ; Pet *m_Pet ; Veterinarian *m_Vet ; public: PetOwner(); PetOwner(const PetOwner& obj); PetOwner *makeCopy() const ; virtual ~PetOwner(); PetOwner &operator=(const PetOwner &rhs) ; const string & GetName () const ; void SetName (const string & val) ; const Pet * GetPet () const ; void SetPet (Pet *val) ; void ClearPet () ; const Veterinarian * GetVet () const ; void SetVet (Veterinarian *val) ; void ClearVet () ; } ; // Class Veterinarian -------------------------------- class Veterinarian { string m_Name ; string m_StreetAddress ; string m_Town ; string m_Phone ; public: Veterinarian(); Veterinarian(const Veterinarian& obj); Veterinarian *makeCopy() const ; virtual ~Veterinarian(); Veterinarian &operator=(const Veterinarian &rhs) ; const string & GetName () const ; void SetName (const string & val) ; const string & GetStreetAddress () const ; void SetStreetAddress (const string & val) ; const string & GetTown () const ; void SetTown (const string & val) ; const string & GetPhone () const ; void SetPhone (const string & val) ; } ; // Class Pet -------------------------------- class Pet { string m_Name ; string m_KindOfPet ; public: Pet(); Pet(const Pet& obj); Pet *makeCopy() const ; virtual ~Pet(); Pet &operator=(const Pet &rhs) ; const string & GetName () const ; void SetName (const string & val) ; const string & GetKindOfPet () const ; void SetKindOfPet (const string & val) ; } ; #endif Listing Four #include "pets.hxx" ////////////////////////////////////////////////////////// // class PetOwner PetOwner::PetOwner() { m_Pet = NULL; m_Vet = NULL; } PetOwner::PetOwner(const PetOwner& obj) { m_Name = obj.m_Name; m_Pet = obj.m_Pet->makeCopy(); m_Vet = obj.m_Vet; } PetOwner *PetOwner::makeCopy() const { return new PetOwner(*this); } PetOwner::~PetOwner() { delete m_Pet ; } PetOwner & PetOwner::operator=(const PetOwner &rhs) { if (this == &rhs) return *this ; // No changes if assignment to self m_Name = rhs.m_Name; m_Pet = rhs.m_Pet->makeCopy(); m_Vet = rhs.m_Vet; return *this ; } ////////////////////////////////////////////////////////// // class Veterinarian Veterinarian::Veterinarian() { } Veterinarian::Veterinarian(const Veterinarian& obj) { m_Name = obj.m_Name; m_StreetAddress = obj.m_StreetAddress; m_Town = obj.m_Town; m_Phone = obj.m_Phone; } Veterinarian *Veterinarian::makeCopy() const { return new Veterinarian(*this); } Veterinarian::~Veterinarian() { } Veterinarian & Veterinarian::operator=(const Veterinarian &rhs) { if (this == &rhs) return *this ; // No changes if assignment to self m_Name = rhs.m_Name; m_StreetAddress = rhs.m_StreetAddress; m_Town = rhs.m_Town; m_Phone = rhs.m_Phone; return *this ; } ////////////////////////////////////////////////////////// // class Pet Pet::Pet() { } Pet::Pet(const Pet& obj) { m_Name = obj.m_Name; m_KindOfPet = obj.m_KindOfPet; } Pet *Pet::makeCopy() const { return new Pet(*this); } Pet::~Pet() { } Pet & Pet::operator=(const Pet &rhs) { if (this == &rhs) return *this ; // No changes if assignment to self m_Name = rhs.m_Name; m_KindOfPet = rhs.m_KindOfPet; return *this ; } Example 1: :// :// Class ------------- :// : :class \ :: \ .each_parent :\ :, : .end :{ Example 2: PetOwner::~PetOwner() { delete m_Pet ; }