Download presentation
Presentation is loading. Please wait.
1
1 Classes with Pointer Data Members (II) Ying Wu Electrical Engineering & Computer Science Northwestern University yingwu@ece.northwestern.edu EECS 230 Lectures Series
2
2 How to handle it? Classes with pointer data members are special, and need more attentions! How to handle it? –Destructor –Copy constructor –Assignment Assignment function Overloading = Using this Avoiding self-destruction Enabling cascading
3
3 Another Example Task: construct a class for string, instead of using char*. Everything seems easy. What should we pay more attention to?
4
4 1 st version class CString { public: CString(); CString(const char*); ~CString(); void set(const char* data); const char *get() const { return m_str; } ; private: char *m_str; };
5
5 CString::CString() { m_str = NULL; } CString::CString(const char* data) { m_str = new char [strlen(data) + 1]; strcpy(m_str, data); } CString::~CString() { delete [] m_str; } void CString::set(const char* data) { if(m_str) delete [] m_str; m_str = new char [strlen(data) + 1]; strcpy(m_str, data); }
6
6 2 nd version class CString { public: CString(); CString(const char*); CString(const CString& s);// copy constructor ~CString(); void set(const char* data); const char *get() const { return m_str; }; private: char *m_str; };
7
7 Copy Constructor // copy constructor, we don’t need delete here CString::CString(const CString &s) { str = str_dup_new(s.get()); }; A copy constructor doesn’t need to dealloate memory, since the object has not been created yet; A copy constructor never needs to check whether auto- duplication occurs. No variable can be initialized with itself
8
8 3 rd version class CString { public: CString(); CString(const char*); CString(const CString &s);// copy constructor ~CString(); const CString& operator=(const CString& s); // assignment void set(const char* data) { str_dup_new(data); }; const char *get() const { return m_str; }; private: char *m_str; };
9
9 Operator overloading const CString & CString::operator=(const CString &s) { if(this != &s){ // check self-destruction delete [] m_str; m_str = str_dup_new(s.get()); } return (*this); // enable cascading }
10
10 Initialization vs. assignment void main() { CString a(“Hello World\n”); CString b; CString c = a; // which constructor? CString d(a); // which constructor? b = c; // assignment } Initialization: call a constructor. Whenever an object is created, a constructor is needed Assignment: call assignment member function
11
11 A more elegant solution Observations: –The duplication occurs (1) in the copy constructor; (2) in the overloading assignment function –The deallocation occurs (1) in the overloading assignment function; (2) in the destructor Using two private member functions like copy() and destory()
12
12 4 th version class CString { public: CString(); CString(const char*); CString(const CString &s); // copy constructor ~CString(); const CString &operator=(const String &s); void set(const char* data); const char *get() { return m_str; } const ; private: char *m_str; void _copy(const CString &s); void _destroy() { delete [] m_str; }; };
13
13 CString::_copy(const CString &s) { m_str = str_dup_new( s.get() ); } CString::CString(const CString &s) { _copy(s); }; CString::~CString() { _destroy(); }; const CString & CString::operator=(const CString &s) { if(this != &s){ _destroy(); _copy(s); } return (*this); }
14
14 Static Let’s learn something special
15
15 An interesting problem Suppose I have a function, say myfunc(), in my tool library. This function is widely used, e.g., it is called in many places in my program which may include many source files. Question: I want to know how many times this function has been called in my program. How can I do this safely, efficiently, and elegantly?
16
16 1 st version: Global variables extern int g_count = 0; void myfunc() { g_count ++; cout << “The “<<g_count <<“-th time call myfunc().\n”; } int main() { for(int i=0;i<10;i++) myfunc(); return 0; } Using global variables is not a good practice!
17
17 An Elegant Solution void myfunc() { static int s_count = 0; s_count ++; cout << “The “<<s_count <<“-th time call myfunc().\n”; } int main() { for(int i=0;i<10;i++) myfunc(); return 0; } Get rid of global stuff and encapsulate Pay attention to the initialization of static variables
18
18 Question? What is the output of the following code? int myfunc(int n) { static int m = 10; int p = 1; p *= 2; m += p; return m+n; } void main() { for(int k=0;k<30;k+=10) cout << myfunc(k) << endl; }
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.