Classes n Special member functions n n constructors
Classes n Special member functions: n n constructors n have the same name as the class n are used to initialize the data members n are invoked automatically when class objects are created n do not have a return type destructor n has the same name as the class preceded by a tilde (~) n is used to perform housekeeping (such as memory deallocation) when a class object is destroyed n is invoked automatically when class objects are destroyed n does not have arguments n does not have a return type n is ESSENTIAL when there are pointer data members 1
Classes n When a data member is a pointer, the constructor must allocate space for it and the destructor must deallocate space. class Grade. Info { n Example: private: int *scores; int class_size; public: Grade. Info (int class_size = 1) { scores = new int[class_size]; for (int i=0; i<class_size; i++) scores[i] = 0; } ~Grade. Info() { delete [ ] scores; } }; 2
Copy constructor n There are certain situations when a copy of an object must be made: n when passing the object by value n when returning an object n Furthermore, we want to be able to initialize an object by another object. n e. g. Grade. Info quiz 1 (11); // Now declare copy, a new Grade. Info object that is meant // to be an exact copy of quiz 1: Grade. Info copy(quiz 1); n Creating a copy of an object is the job of the copy constructor. n A special kind of constructor that takes as argument an object of the same type as the class. 3
Copy constructor n If a copy constructor is missing, the compiler creates a default one performs member-by-member copying. n A default copy constructor for the Member. Info class would look like this: Grade. Info (const Grade. Info& init) { scores = init. scores; class_size = init. class_size } n As we will see, this is INCORRECT in this case! n Consider the following piece of code: Grade. Info *quiz = new Grade. Info (5); quiz->read_grades(); // reads in the quiz grades Grade. Info backup(*quiz); delete quiz; quiz = NULL; continue on next slide. . . 4
Copy constructor & pointers 1: Grade. Info *quiz = new Grade. Info (11); quiz->read_grades(); quiz: 10 9 13 2 7 9 5 2: Grade. Info backup(*quiz); Let's look inside the copy constructor: scores = init. scores; class_size = init. class_size quiz: 5 10 9 13 2 7 9 backup: 5 continue on next slide. . . 5
Copy constructor & pointers 3: delete quiz; quiz = NULL; quiz: 0 freed memory backup: 5 backup and quiz should be independent objects. Modifying one should not affect the other. When pointers are involved, the copy constructor must explicitly allocate space and copy the appropriate value. (IOW, it must make a deep copy) See the next slide for a correct version of the copy constructor. 6
Copy constructors & pointers Grade. Info (const Grade. Info& init) { scores = new int[init. class_size]; class_size = init. class_size; for (int i=0; i<class_size; i++) scores[i] = init. scores[i]; } 7
operator= n A problem similar to that of the copy constructor appears when we use assignments. n If quiz and backup are two Grade. Info objects, then by default, quiz = backup; will perform a member-by-member assignment. n To avoid the problem, the assignment operator must be overloaded by the programmer, so that it performs a deep assignment. n We will learn about overloading later. . . 8
pointer data members n Whenever a class has at least one data member that is a pointer, you MUST write n n n a destructor a copy contructor an overloaded assignment operator THE BIG THREE! If you need one of them, then you also need the other two! 9
- Slides: 9