1 / 104

C++ & Object-Oriented Programming

C++ & Object-Oriented Programming. The Class. A class is a unit of encapsulation. Public operations, and private implementation. A class is an abstraction. String abstracts the char * of C, stack -- the canonical abstraction List Student, etc. Classes and C structures.

kirti
Télécharger la présentation

C++ & Object-Oriented Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. C++ & Object-Oriented Programming The Class

  2. A class is a unit of encapsulation • Public operations, and • private implementation.

  3. A class is an abstraction • Stringabstracts the char * of C, • stack -- the canonical abstraction • List • Student, • etc.

  4. Classes and C structures • default access for class: private • default access for struct:public This is the only difference between a C++ class and a C++ structure.

  5. Classes • Example of a bad class declaration class Student { public: float gpa; char * name; };

  6. Classes and structures • Correct example of Class Declaration class Student { private: float gpa; char * name; }; • do we need the “private” designation? How do I access the "private" data?

  7. Classes: writing set and getfunctions provide accessor and modifier functions class Student { public: void setGpa(float g) { gpa = g; } void setName(char * n) { name = new char[strlen(n)+1]; strcpy(name, n); } private: float gpa; char * name; }; What's missing?

  8. Classes and Objects • Declaration of a class variable (i.e. object) Student s, t; Student * v; int i; float x; • The syntax is identical to conventional variable declarations. This one is on the stack. This one will be on the heap.

  9. Classes • Since class declarations will likely be used by many program modules, put them in a header file that can be included as required #include “Student.h”

  10. Classes and Objects function call • Access to class data members s.setGpa(3.5); s.setName(“Dana”); v = new Student(4.0, “Fox”); t = s; • The Student class also needs constructors shallow copy?

  11. Classes: constructors class Student { public: Student(); //default Student(char*, float); //conversion Student(const Student&); //copy friend ostream & operator<<(ostream &, const Student &); private: char * name; float gpa; }; This is an example of an improper class definition!

  12. Constructor parameters: • Default: no parameters • Conversion: parameters to make one • Copy: the parameter is the copy instance Default is used with arrays of objects. Copy is used with "pass by value"

  13. Constructors/destructors • Guarantee that data is initialized • allow classes to manage memory • constructors allocate: new • destructors deallocate: delete Especially important for heap based memory

  14. Prefer initialization to assignment class Student { public: Student(int a) : age(a), iq(age+100) {} Student(int a) { age = a; iq = age + 100; } private: int age; int iq; };

  15. Prefer init to assign • Initialization is more efficient for data members that are objects: • init: uses copy constructor • assign: uses default constructor and assignment • only way to pass a parameter to base class

  16. Passing param to base class class Person { public: Person(int a) : age(a) {} private: int age; }; class Student : public Person { public: Student(int age, float g) : Person(age), gpa(g) {} private: float gpa; };

  17. List members in init list in order that they are declared class members are initialized in the order of their declaration in the class! What’s the value of iq? class Student { public: Student(int a) : age(a), iq(age+100) {} private: int iq; int age; };

  18. Exercise to learn constructors • Write 3 constructors and a destructor for Student class. Test it with: void fun(Student stu) {} int main() { Student a, b(“Darth Maul”, 3.5), c = b; Student * d = new Student(“Anakin”, 4.0); cout << *d << endl; fun(a); return 0; }

  19. Why is this a bad class definition?at least 2 member functions missing class Student { public: Student(); //default Student(char*, float); //conversion Student(const Student&); //copy friend ostream & operator<<(ostream &, const Student &); private: char * name; float gpa; }; This is an example of an improper class definition!

  20. Q: what output should we get: int main() { Student x(“Count Dooku”), y(“Anakin”); x = y; y.setName(“Darth Maul”); cout << x << endl; } Soln: needdeep copy: operator=

  21. Copying a class object Original Object Shallow Copy

  22. Copying a class object Original Object Deep Copy

  23. Canonical orthodox class form J. Coplien • Default constructor • copy constructor • destructor • assignment operator operator<<

  24. What functions does C++silently write? class Empty{}; class Empty { public: Empty(); Empty(const Empty &); ~Empty(); Empty& operator=(const Empty &); Empty * operator&(); const Empty * operator&() const; }; If you write this You get this; if needed!

  25. How would you need them? const Empty e1; // need default constructor, and // destructor Empty e2(e1); // copy constructor e2 = e1; // assignment operator Empty * pe2 = &e2; // address-of operator (non const) const Empty *pe1 = &e1; // address-of operator (const)

  26. What do the compiler generated functions look like? inline Empty::Empty() {} inline Empty::~Empty() {} inline Empty * Empty::operator&() { return this; } inline const Empty * Empty::operator&() const { return this; } The copy constructor and assignment operator simply do a member wise copy, i.e., shallow. Note that the default assignment induces a memory leak in Student! note: destructor is NOT virtual

  27. When do we need to write a copy constructor, destructor & assign operator? • Anytime the class has heap-based data members • all base classes should have a virtual destructor • Studies have shown that, if you don’t need copy/assign, the compiler generated functions run 10-20% faster than programmer generated ones.

  28. How do we overload assignment? Student & operator=(const Student & stu) { if (*this == stu) return * this; delete [] name; name = new char[strlen(stu.name)+1]; strcpy(name, stu.name); gpa = stu.gpa; return *this; } (1) Why the comparison on the first line? (2) Could the first line be: if (this == &stu)? (3) Why return *this? What does it enable? (4) Why not return stu, rather than *this?

  29. Formula for overloaded assignment • Check for equality of lhs & rhs • delete storage for lhs • create new storage for lhs, that’s size of rhs • copy rhs “stuff” to lhs • return *this

  30. an overloaded binary operator • can be written in infix form • a = b; • cout << stu; • or can be written in prefix form • a.operator=(b) • cout.operator<<(stu) here it's more obvious what "this" is

  31. Principle of least privilege • Can reduce debugging and provide documentation by only allowing a function the least amount of privilege • can prevent a function from modifying a parameter • can prevent a member function from modifying data attributes • allow a function enough data access to accomplish its task – and no more!

  32. Explicitly disallow any implicit functions you don’t want! • Suppose you want to write a class template array that behaves like C++ arrays, except that it does bounds check • C++ does not allow array assignment; e.g. int a[10], b[10]; a = b; //error don’t define the operator= to keep member & friend functions from using it! class Array { private: Array & operator=(const Array & ); };

  33. Overloading operators • almost all operators can be overloaded • operators are binary or unary • have the same precedence as their compiler counterpart • can be members or friends, usually • overloaded output operator cannot be a member of any user defined class

  34. overloading output operator:as a friend function class Student { public: getName() { return name; } getGpa() { return gpa; } friend ostream & operator<<(ostream &, const Student &); private: char * name; float gpa; }; ostream & operator<<(ostream & out, const Student & s) { out << s.getName() << “\t” << s.getGpa(); return out; }

  35. Overloading output operator:as stand-alone function class Student { public: getName() { return name; } getGpa() { return gpa; } private: char * name; float gpa; }; ostream & operator<<(ostream & out, const Student & s) { out << s.getName() << “\t” << s.getGpa(); return out; } What's wrong with this class definition?

  36. Put prototype in header file,and body in implementation file class Student { public: getName() const { return name; } getGpa() const { return gpa; } private: char * name; float gpa; }; ostream & operator<<(ostream &, const Student &); ostream & operator<<(ostream & out, const Student & s) { out << s.getName() << “\t” << s.getGpa(); return out; } header file implementation file

  37. Exercise with classes: • Complete the definition of Student with all 3 constructors, overloaded assignment, overloaded output, and get and set • Write a main program that contains 2 functions: • a function to init the list with 3 Students • a function that prints the list

  38. Using students • In actual practice, we want to store lots of students • need an array of students Student list[10]; Q: How many times does a constructor get called for list? Q: which constructor?

  39. What’s missing: • Need an easier way to print a student • overload the output operator << • operator<< must be a friend function; cannot be a member function cuz it’s already a member of class ostream • Need a class to manage the list of Students

  40. Friends • Can access private member functions and private data attributes! • Can be functions or classes • Might not always be best solution!

  41. Overloading the output operator Class Student { public: friend ostream & operator<<(ostream & out, const Student & student){ out << student.name; return out; } };

  42. Class StudentManager { public: StudentManager() : count(0) { } void insert(const Student &); friend ostream & operator<<(ostream &, const Student &); private: int count; Student list[100]; }; 42 42

  43. Class StudentManager { public: StudentManager() : count(0) {} void insert(const Student & student) { list[count++] = student; } friend ostream & operator<<(ostream & out, const Student & student) { for (int i = 0; i < count; ++i) out << student[i] ;<< endl; return out; } private: int count; Student list[100]; }; 43 43

  44. Class exercise: • Complete the StudentManager Class; • rewrite main to use the List Class. • Write a new main program that allows the user to choose among commands: • insert student • delete student • print the list • find a student • exit

  45. Discussion of Manager class: • Advantages: • encapsulates functionality into a single class • simplifies the main program • Disadvantages: • there is a limit (100) on number of Students • Student’ default constructor called 100 times!

  46. Suggested Naming Conventions • global constants: ALL CAPS! • local & global variables: ALL LOWER CASE, USE UNDERSCORE • Class names: BEGIN EACH WORD WITH UPPER CASE, NO UNDERSCORE • Class member functions: BEGIN LOWER CASE, then BEGIN EACH WORKD WITH UPPER CASE • Data members: SAME AS MEMBER FUNCTIONS

  47. Operator Overloading:ADT for binary math • Would like variables of type binary to be like any other data type. Thus: • overload arithmetic operators • overload output to be binary • overload input to use decimal • How do we represent internally?

  48. Binary should “look like” int #include “Binary.h” main() { int sum = 0; Binary number1, number2 = 7; number1 = 15; cout << number1 + number2 << endl; }

  49. // This is file Binary.h class Binary { public: Binary() : number(0) {} Binary(int n) : number(n) {} Binary(const Binary & bin); Binary operator+(const Binary &); Binary& operator++(); Binary& operator=(const Binary &); friend ostream & operator<<(ostream &, const Binary &); private: int number; }; Where's the destructor? 49 49

  50. #include “Binary.h” // this is file Binary.cpp Binary Binary::operator+(const Binary & rhs) { Binary temp(number+rhs.number); return temp; } Binary& operator++() { ++number; return *this; } 50 50

More Related