In addition to defining how objects of the class type are initialized, classes also control what happens when we copy, assign, or destroy objects of the class type. Objects are copied in several contexts, such as when we initialize a variable or when we pass or return an object by value (§ 6.2.1, p. 209, and § 6.3.2, p. 224). Objects are assigned when we use the assignment operator (§ 4.4, p. 144). Objects are destroyed when they cease to exist, such as when a local object is destroyed on exit from the block in which it was created (§ 6.1.1, p. 204). Objects stored in a vector
(or an array) are destroyed when that vector
(or array) is destroyed.
If we do not define these operations, the compiler will synthesize them for us. Ordinarily, the versions that the compiler generates for us execute by copying, assigning, or destroying each member of the object. For example, in our bookstore program in § 7.1.1 (p. 255), when the compiler executes this assignment
total = trans; // process the next book
it executes as if we had written
// default assignment for Sales_data is equivalent to:
total.bookNo = trans.bookNo;
total.units_sold = trans.units_sold;
total.revenue = trans.revenue;
We’ll show how we can define our own versions of these operations in Chapter 13.
Although the compiler will synthesize the copy, assignment, and destruction operations for us, it is important to understand that for some classes the default versions do not behave appropriately. In particular, the synthesized versions are unlikely to work correctly for classes that allocate resources that reside outside the class objects themselves. As one example, in Chapter 12 we’ll see how C++ programs allocate and manage dynamic memory. As we’ll see in § 13.1.4 (p. 504), classes that manage dynamic memory, generally cannot rely on the synthesized versions of these operations.
However, it is worth noting that many classes that need dynamic memory can (and generally should) use a vector
or a string
to manage the necessary storage. Classes that use vector
s and string
s avoid the complexities involved in allocating and deallocating memory.
Moreover, the synthesized versions for copy, assignment, and destruction work correctly for classes that have vector
or string
members. When we copy or assign an object that has a vector
member, the vector
class takes care of copying or assigning the elements in that member. When the object is destroyed, the vector
member is destroyed, which in turn destroys the elements in the vector
. Similarly for string
s.
Until you know how to define the operations covered in Chapter 13, the resources your classes allocate should be stored directly as data members of the class.