PRODUCT : Borland C++ NUMBER : 1540 VERSION : All OS : All DATE : October 25, 1993 PAGE : 1/4 TITLE : Copy semantics /* Copy semantics - making safe copies of C++ objects. * * Making copies of C++ objects infers the concepts of "deep" * and "shallow" copies. A shallow copy is a memberwise copy, * whereas a deep copy constructs an object which has its own * copies of any dynamically allocated members. The distinction * between deep and shallow copies becomes very important in * cases where we dynamically allocate memory in a constructor * and then release it in the destructor. For example, examine * this code: * * class CopySem * { * char * str; * public: * CopySem() { str = new char [ 20 ]; } * ~CopySem() { delete str; } * const char * Name() { return str; } * }; * * CopySem c1, c2; * c1 = c2; * * As we have given no special instructions for how to * initialize one class with another, a simple or "shallow" copy * will be made. This means that c1.str will get the value of * c2.str and both pointers will reference the same memory. When * c1 and c2 are destructed, we will effectively delete the same * 'str' object twice, which will result in heap corruption. The * solution is to provide copy semantics which ensure a "deep" * copy. In a deep copy, memory is allocated for c1.str and that * memory is initialized with the information referenced by * c2.str. This should be done by defining both a copy * constructor (a constructor which takes a const reference to * an instance of its same type) and by overloading the * assignment operator. * * Note: If you are writing C++ code, all of your classes * should have the prototypes for a copy constructor and an * assignment operator defined. If you are writing code in which * these functions should never be called, you can get the * compiler to assist in finding such occurrences by defining * these operators without any supporting code and making them PRODUCT : Borland C++ NUMBER : 1540 VERSION : All OS : All DATE : October 25, 1993 PAGE : 2/4 TITLE : Copy semantics * private. This way, a compilation error will result if they * are called from anywhere but a member function. If they are * called from a member function, there will be a linker error * because the functions have no supporting code. This technique * can save significant debugging time on a large scale * applications. */ #include // cout #include // strlen, strcpy class CopySem { char * str; public: CopySem() : str( 0 ) {} // Default constructor CopySem( char * intStr ); CopySem( const CopySem& c ); // Copy Constructor ~CopySem() { delete str; } CopySem& operator=( const CopySem& c ); const char * Name() { return str; } }; CopySem::CopySem( char * initStr ) { str = new char [ strlen( initStr ) + 1 ]; if( str ) strcpy( str, initStr ); } CopySem::CopySem( const CopySem& c ) { str = new char[ strlen( c.str ) + 1 ]; if( str ) strcpy( str, c.str ); } CopySem& CopySem::operator=( const CopySem& c ) { PRODUCT : Borland C++ NUMBER : 1540 VERSION : All OS : All DATE : October 25, 1993 PAGE : 3/4 TITLE : Copy semantics /* If this object has already been initialized, we need to * release the memory referenced by str. If this object was * constructed by the default constructor, the str == NULL and it * is legal to call delete on a null pointer without adverse side * effects. */ delete str; str = new char[ strlen( c.str ) + 1 ]; if( str ) strcpy( str, c.str ); /* Returning a reference ensures that c1 = c2 = c3 works. */ return *this; } int main( int, char ** argv ) { CopySem c1( argv[0] ); /* c2 is created by calling the copy constructor */ CopySem c2( c1 ); /* c3 is created with the default constructor and then * initialized by calling the overloaded operator=. */ CopySem c3; c3 = c2; /* Notice that the pointers are all different but the * contained information, the strings, are all the same; */ cout << (void * ) c1.Name() << " " << c1.Name() << endl; cout << (void * ) c2.Name() << " " << c2.Name() << endl; cout << (void * ) c3.Name() << " " << c3.Name() << endl; return 0; } DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that PRODUCT : Borland C++ NUMBER : 1540 VERSION : All OS : All DATE : October 25, 1993 PAGE : 4/4 TITLE : Copy semantics you received with the Borland product to which this information pertains.