CS32 Discussion Section 1B Week 2 TA: Hao Yu (Cody)
Discussion Section 1B Hao Yu (Cody) Usually reply mails at 10:30/22:00 Office hours Tue. – Thu. 9:30 – 10:30 a.m. BH 2432 Attend lecture 1 You can also find me there
Reminder & Agenda Debugging New and Delete Copy Constructor Operator Overloading Homework 1 due next Tuesday 9:00 p.m.
How to Use Debugging int foo(int N) { int out; out = foo(N - 1) + foo(N - 2); return out; } int main(void) { int N = 10; cout << "N = " << N << endl; int result; result = foo(N); cout << result << endl; return 0; } Fibonacci number generator … with bugs
How to Use Debugging DEMO Set/clean breakpoints Single step Step over Step into Step out Run to next breakpoint Look at the values of local variables Look at the stack trace
New and Delete How to use them? When will you use them? Don’t know the size of the array in advance Use them with class! int *ary = new int[10]; delete ary []; int *ary; int N; cin >> N; ary = new int[N]; delete [] ary;
New and Delete class History { public: History(int nRows, int nCols) : m_rows(nRows), m_cols(nCols) { for (int r = 0; r < m_rows; r++) for (int c = 0; c < m_cols; c++) m_grid[r][c] = 0; }... private: int m_rows; int m_cols; int m_grid[MAXROWS][MAXCOLS]; } Challenge: Modify History class to allow user to input arbitrary rows and columns
New and Delete class History { public: History(int nRows, int nCols) : m_rows(nRows), m_cols(nCols) { for (int r = 0; r < m_rows; r++) { for (int c = 0; c < m_cols; c++) m_grid[r][c] = 0; }... private: int m_rows; int m_cols; int **m_grid; } When will the program know the right number? grid = new int*[m_rows]; grid[r] = new int[m_cols]; Are we done? NO!! Don’t forget to delete them!
Scope class History { public: History(int nRows, int nCols) : m_rows(nRows), m_cols(nCols) { for (int r = 0; r < m_rows; r++) { for (int c = 0; c < m_cols; c++) m_grid[r][c] = 0; } ~History() { for (int r = 0; r < m_rows; r++) delete [] m_grid[r]; delete [] m_grid; } …… grid = new int*[m_rows]; grid[r] = new int[m_cols]; New and delete must be a pair!!
Scope class History { public: History(int nRows, int nCols) : m_rows(nRows), m_cols(nCols) { grid = new int*[m_rows]; for (int r = 0; r < m_rows; r++) { grid[r] = new int[m_cols]; for (int c = 0; c < m_cols; c++) m_grid[r][c] = 0; } ~History() { for (int r = 0; r < m_rows; r++) delete [] m_grid[r]; delete [] m_grid; } …… Class instanceFunction int foo(void) { int *ary = new int[10];... delete [] ary; }
Scope Challenges – Find the problem bool Arena::attackRobotAt(int r, int c, int dir) { History m_history(MAXROWS, MAXCOLS);... if (...) { // robot dies... m_history.record(r, c); return true; } return false; } class Arena { …… private: int m_rows; int m_cols; Player* m_player; Robot* m_robots[MAXROBOTS]; int m_nRobots; History m_history; }; this.m_history construct attackRobotAt.m_history deconstruct attackRobotAt.m_history !! Bonus: Can you still access this.m_history in this function? Sol: this.m_history
New and Delete How about the class inside another class? #define MAX_STUDENT 100 class School { public: School(const string &name); School(const string &name, const int maxStudent); string getName() const; void setName(const string &name); void addStudent(const Student &student); Student *getStudent(const string &name); bool removeStudent(const string &name); int getNumStudents() const; private: string m_name; Student *m_students; int m_numStudents; }; class Student { public: Student(int n) { name = n; gpa = 0.0; } string getName() { return name; } void setGPA(double g) { gpa = g; } double getGPA() { return gpa; } private: string name; double gpa; }
New and Delete Can you write the constructor/deconstructor? #define MAX_STUDENT 100 School::School(const string &name) { m_students = new Student[MAX_STUDENT]; m_name = name; m_numStudents = 0; } School::School(const string &name, const int maxStudent) { m_students = new Student[maxStudent]; m_name = name; m_numStudents = 0; } School::~School() { delete [] m_students; }
Copy Constructors Student st1("Brian"); Student st2("John"); School s1("UCLA"); s1.addStudent(st1); s1.addStudent(st2); UCLA s1 BrainJohn Now the government wants to create a new school – UCLA Game School, and all UCLA students can be a student of that school as well FOR FREE UCLA Game s2 BrainJohn
Copy Constructors Candidate 1: Assignment What’ s the problem with this method? School s2(""); s2 = s1; s2.setName(“UCLA Game”);
Copy Constructors Candidate 1: Assignment Correctness Every member variable gets copied – even the pointers (but not the pointees) Efficiency Construct s2, initial s2 members, copy values from s1 to s2 School s2(""); s2 = s1; s2.setName(“UCLA Game”); UCL A s1 BrainJohn UCLA Game s2
Copy Constructors Candidate 2: Copy values School s2(""); s2.setName(“UCLA Game”); // then what??
Copy Constructors Candidate 2: Copy values We may not have accessors and modifiers to all member variables! It is often not desirable to have the user (of a class) know all the internals. Too long to write! School s2(""); s2.setName(“UCLA Game”); // then what??
Copy Constructors This is a constructor that is used to copy values from one instance to another. Why do you think the parameter is a constant reference? public: School(const School &aSchool);
Copy Constructors Why you can access private members!? Access control works on classes, not on objects Remember to allocate new memory for the new class instance School::School(const School &aSchool) { m_name = aSchool.m_name; m_numStudents = aSchool.m_numStudents; m_students = new Students[m_numStudents]; for (int i = 0; i < m_numStudents; i++) m_students[i] = aSchool.m_students[i]; }
Copy Constructors Now, life is beautiful… School s2(s1); s2.setName("UCLA Game"); School s2 = s1; s2.setName("UCLA Game");
However, Candidate 1 is Really Useless? s2 = s1; UCL A s1 BrainJohn UCLA Game s2 UCL A s1 BrainJohn
Operator Overloading Overload the operator s2 = s1; public: School& operator=(const School &aSchool) School& operator+(const School &aSchool) School& operator-(const School &aSchool) School& operator*(const School &aSchool) ……
Operator Overloading School& operator=(const School &aSchool) { m_name = aSchool.m_name; m_numStudents = aSchool.m_numStudents; m_students = new Students[m_numStudents]; for (int i = 0; i < m_numStudents; i++) m_students[i] = aSchool.m_students[i]; } Are we done? Enable the chain! Manage the memory well! Avoid to get high! return *this; delete [] m_students; if (&aSchool != this) { }
Last… Homework 1 Today’s discussion must be useful You can use array to finish it – without linked list … but you have to use that in project 2 Q&A