Introduction This article talks about Handle-Body pattern and it's uses. Background Though, C++ provides private and public access specifiers to differntiate implementation and interface parts of a class, down the line any changes to the private data or member functions implementation would lead to re-compile the whole class. So instead, it is useful to put interface (public section of a class) and implemntation (private section of a class) details in a 2 seperate classes named as "Handle" and "Body" respectively. And provide a pointer of "Body" class to the "Handle" class. Then make "Handle" forwarding function calss to "Body". Then provide only the interface class to clients. Uses: Here any changes to the implmentation class can be made safely without disturbing or re-compiliing the interface class and thus reducing the compilation time. Also here the implementation becomes more hidden to the clients and thus achiving more encapsulation. Future maintainace will also be much easier (if you decide to add or remove any data in the implementation details, will not affect the client's code) Since the data here is kept seprately with the implemetation class, this pattern is well suited to provide reference-counting facility and thus reliveing developers with the task of memory management as well. Here is a sample code of Handle and Body class. The code Code: // ********* body.h - Declares Body class *********** #include <iostream.h> class Body { public: // Body features: int get_value () const; void set_value (int val); // standard construction and destruction: Body (); Body (const Body&); Body& operator = (const Body&); ~Body (); //void swap (Body&); private: int myVal; }; // ********* End of body.h file ********** // ********* body.cc - Implementation details of "Body" class ********* #include "body.h" Body::Body() { cout<<"Body::default constructor = \n"; } Body::Body (const Body& rhs) { cout<<"Body::copy constructor = \n"; myVal = rhs.myVal; } Body& Body::operator = (const Body &rhs) { cout<<"Body::operator = \n"; if(this != &rhs) { myVal = rhs.myVal; return (*this); } } Body::~Body() { cout<<"Body::Destructor\n"; } int Body::get_value() const { cout<<"Body::getValue- myValue = "<<myVal<<"\n"; return (myVal); } void Body::set_value(int val) { myVal = val; cout<<"Body::set_value-myValue = "<<myVal<<"\n"; } // ******** End of body.cc file ********** // ******** handle.h - Declares Handle class ********* class Body; // no #include, but forward declaration class Handle { public: // Handle features: int get_value () const; void set_value (int val); // standard construction and destruction: Handle(); Handle(const Handle&); Handle& operator = (const Handle&); void swap (Handle&); ~Handle (); private: Body * rep_; // pointer to "Body" class }; // ******** End of handle.h file ************ // ********* handle.cc - Implementation details of Handle class *********** #include "handle.h" // get the interface #include "body.h" // get the implementation Handle::Handle () { cout<<"Handle::default constructor = \n"; rep_= new Body; } Handle::Handle (const Handle& rhs) : rep_(0) { cout<<"Handle::copy constructor = \n"; rep_= new Body (*rhs.rep_); } Handle& Handle::operator = (const Handle &rhs) { cout<<"Handle::operator = \n"; if (this != &rhs) { *(rep_) = *(rhs.rep_); return (*this); } } void Handle::swap (Handle& rhs) { Body * tmp = rhs.rep_; rhs.rep_= rep_; rep_= tmp; } Handle::~Handle () { cout<<"Handle::Destructor\n"; delete rep_; rep_= 0; } int Handle::get_value () const { cout<<"Handle::getValue- myValue\n"; return rep_->get_value (); } void Handle::set_value (int val) { rep_->set_value (val); cout<<"Handle::set_value-myValue\n"; } // Here is client code, that uses Handle class int main() { Handle h; h.set_value(10); h.get_value(); return(0); } // *********** End of handle.cc file *************
thanks Shabbir. I have not introduced myself before, I should have been but. Anyway, I am frm Blr , working on C, C++ with 5 yrs exp. and new to this Forum and would like to share some of my learnings here. thanks.
Good Article...Keep it posting... One thing in assignment operator you should write statement return *this out of if condition.