Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Classes with Pointer Data Members (II) Ying Wu Electrical Engineering & Computer Science Northwestern University EECS 230.

Similar presentations


Presentation on theme: "1 Classes with Pointer Data Members (II) Ying Wu Electrical Engineering & Computer Science Northwestern University EECS 230."— Presentation transcript:

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; }


Download ppt "1 Classes with Pointer Data Members (II) Ying Wu Electrical Engineering & Computer Science Northwestern University EECS 230."

Similar presentations


Ads by Google