Memberwise Assignment / Initialization The assignment operator, =, is used in two ways: to assign one object to another, or to initialize an object with an object’s data Examples (assuming class V): V v1, v2; … // statements that assign … // values to members of v1 v2 = v1; // assignment V v3 = v2; // initialization See pr11-05.cpp
Assignment When the assignment operator, =, is applied to objects, it copies the data member values of the object on the right to the data members of the object on the left. Such an assignment is referred to as memberwise assignment
Assignment For example, consider class Point { public: Point(); Point(double x, double y); . . . // other functions private: double x; double y; }; Point p1(2.0, 3.5); Point p2; The assignment, p2 = p1; assigns p1's data member values to their counterparts in p2, this is memberwise assignment.
Memberwise Assignment Although assignment looks similar to initialization, they are entirely different operations. In an assignment, no new object is created - the value of an existing object is simply changed. In the previous example, the x, y values stored in p2 are originally 0.0 and 0.0, respectively. After assignment, the x, y values are 2.0 and 3.5, respectively. See pr11-05.cpp
Initialization In C++, an initialization occurs every time a new object is created, as in Point p2 = p1; or Point p2(p1); The constructor that performs this type of initialization is called a copy constructor. See pr11-05.cpp
Copy Constructors a constructor function with the same name as the class A copy constructor is one that takes a reference parameter to another object of the same class The copy constructor uses the data in the object passed as parameter to initialize the object being created Reference parameter should be const to avoid potential for data corruption
Copy Constructor Copy constructors are declared in the class declaration, which is generally in the specification file, and defined in the class implementation file. The general form for declaring a copy constructor is classname(const classname &); For example: Point(const Point &pt);
Copy Constructor There are 3 important places where a copy constructor is called: When an object is created from another object of the same type (i.e. the newly created object is initialized to the data of another object of the same class) When an object is passed by value as a parameter to a function When an object is returned from a function
Copy Constructor If a copy constructor is not defined in a class, the compiler itself defines one, called a default copy constructor. A default copy constructor copies field-to-field, using memberwise assignment between objects (shallow copy) The default copy constructor works fine in most cases
Copy Constructor If the class does not have pointer variables with dynamically allocated memory, then the default constructor works fine But, if the class has pointer variables and has some dynamic memory allocations, then it is a must to have a copy constructor.
Initialization vs Assignment Consider the following: class Point { public: … private: double x; double y; }; Point p4; Point p1(2.0, 3.5); Point p2 = p1; // initialization, new object created Point p3 = p1; // initialization, new object created p4 = p1; // assignment, no new object created Both p2 and p3 are newly created objects that are initialized to a previously declared object, p1. For p4, the members are simply changed. See pr11-05.cpp
Copy Constructors Problems occur when objects contain pointers to dynamic storage: class CpClass { public: CpClass(int v=0) { p = new int; *p = v; } ~CpClass() { delete p; private: int *p; };
Default Constructor Causes Sharing of Storage CpClass c1(5); if (true) { CpClass c2=c1; } // c1 is corrupted // when c2 goes // out of scope and // its destructor // executes c1 c2 5
Problems of Sharing Dynamic Storage Destructor of one object deletes memory still in use by other objects Modification of memory by one object affects other objects sharing that memory See pr11-07.cpp, NumberArray.h, and NumberArray.cpp
Programmer-Defined Copy Constructors Used to make a deep copy of the object Avoids problems caused by memory sharing Can allocate separate memory to hold new object’s dynamic member data Can make new object’s pointer point to this memory Copies the data, not the pointer, from the original object to the new object See pr11-08.cpp, NumberArray2.h, and NumberArray2.cpp
Copy Constructor Example class CpClass { public: CpClass(const CpClass &obj){ p = new int; // create a new int object *p = *obj.p; // copy data from obj } CpClass(int v=0) { p = new int; *p = v; ~CpClass(){ delete p; private: int *p; };