1 / 31

C++ Classes: Part II

C++ Classes: Part II. Use of const Composition Friend functions & classes The this pointer Dynamic memory allocation Static class members. Constant Objects. Principle of least privilege Users should be given no more privilege than necessary to perform a job Good software engineering

beyla
Download Presentation

C++ Classes: Part II

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++ Classes: Part II • Use of const • Composition • Friend functions & classes • The this pointer • Dynamic memory allocation • Static class members

  2. Constant Objects • Principle of least privilege • Users should be given no more privilege than necessary to perform a job • Good software engineering • Declaring a constant object • const Fraction f(1,2); • Can only be accessed by member functions that are also declared const

  3. Constant Member Functions • Function prototype void print() const; • Function definition void Fraction::print() const{ cout<<num<<"/"<<den<<endl; } • Constructors & destructors cannot be declared constant • Const member functions cannot modify the object (not allowed by compiler)

  4. Constant Example • Example driver program void main(){ Fraction f1(1,2); const Fraction f2(3,4); f1.multiply(f2); f2.multiply(f1); //gives an error f1.print(); f2.print(); } (See complete program at const.txt)

  5. Constant Data Member • Must modify the constructor to initialize a constant data member class Fraction { const int count; int num, den; public: Fraction(int = 0, int = 0, int = 1); void print() const; }; Fraction::Fraction(int c, int n, int d):count(c){ num = n; den = d; }

  6. Constant Data Member • Alternative way to initialize data members Fraction::Fraction(int c, int n, int d) :count(c), num(n), den(d){} • Print statement void Fraction::print() const{ cout<<count<<":"<<num<<"/"<<den<<endl; } • See complete program at constDataMember.txt

  7. Constant Data Member • Example driver program void main(){ Fraction f1(1,1,2), f2(2,3,4), f3(3,5,6); f1.print(); f2.print(); f3.print(); } /* 1:1/2 2:3/4 3:5/6 */

  8. Passing Parameters • When passing a parameter to a method • Call-by-reference more efficient than call-by-value • Call-by-value creates a “local copy” of the variable with the “copy constructor” • Call-by-reference simple maintains a “place-holder”, as the actual changes are make to the variable in the calling routine • Not a big deal with simple data types (int, etc.) • Can be a big deal with user-defined data types (that contain a lot of data)

  9. For Improved Efficiency • When possible, make parameters call-by-reference • Can speed up execution for some data types • Potential problem • You define the interface for the class’s methods • You have the team write the actual methods • The team is not so bright, so they don’t implement the methods properly

  10. Potential Problem void main(){ Fraction a(2,3); Fraction b(5,7); a.mul(b); a.print(); b.print(); } //output is ?? class Fraction { int i[2]; public: Fraction(int n=0, int d=1){ i[0]=n; i[1]=d;} void mul(Fraction &f){ i[0]=i[0]*f.i[0]; i[1]=i[1]*f.i[1]; f.i[1]=0; } void print() const{ cout<<i[0]<<'/'<<i[1]<<endl; } }; See potentialProblem.txt

  11. Solution: use “const” • Still use reference parameter • Make the parameter a “const”, so cannot change • Solution to mul method void mul( const Fraction &f ){ i[0]=i[0]*f.i[0]; i[1]=i[1]*f.i[1]; f.i[1]=0; /*will be flagged as an error*/ }

  12. Composition • A class can have objects of another class as data members • Example: • Fred (of class Person) has a birthday (of class Date)

  13. #include <iostream> #include <cstring> using namespace std; class Date { int month, day, year; public: Date(int = 1, int = 1, int = 2001); void print() const; }; Date::Date(int m, int d, int y):month(m), day(d), year(y){} void Date::print() const{ cout<<month<<"/"<<day<<"/"<<year<<endl; }

  14. class Person{ char name[20]; const Date birthday; /*Date class*/ public: Person(char[] = "Akira", int = 2, int = 2, int = 2002); void print() const; }; Person::Person(char n[], int m, int d, int y): birthday(m,d,y) { /*Date class*/ int len = strlen(n); strncpy(name,n,len); name[len]='\0'; } void Person::print() const{ cout<<name<<"'s birthday is "; birthday.print(); /*Date class*/ }

  15. Example Driver Program void main(){ Person p1, p2("Toriyama", 10, 31, 1980); p1.print(); p2.print(); } /* Akira's birthday is 2/2/2002 Toriyama's birthday is 10/31/1980 */ (See complete program at composition.txt)

  16. Class Exercise 1 • Class handout (exercise1.txt)

  17. Friend Function • Declaring a function as a friend of a class allows that function to access the private data members of that class

  18. class Person{ friend void changeAge(Person &, int); //appears 1st by convention char name[20]; int age; public: Person(char[] = "Hayao", int = 0); void print() const; }; Person::Person(char n[], int a):age(a){ int len = strlen(n); strncpy(name,n,len); name[len]='\0'; } void Person::print() const{ cout<<name<<" is "<<age<<" years old"<<endl; } void changeAge(Person &p, int x){ p.age+=x; }

  19. Example Driver Program void main(){ Person p("Miyazaki", 55); p.print(); changeAge(p, -5); p.print(); } /* Miyazaki is 55 years old Miyazaki is 50 years old */ (See complete program at friendFunction.txt)

  20. Friend Classes • Allows class1 access to class2’s private data members class Date { friend class Person; int month, day, year; public: Date(int = 1, int = 1, int = 2001); void print() const; }; (See complete program at friendClass.txt)

  21. Friend Classes class Person{ char name[20]; const Date birthday; public: Person(char[] = "Akira", int = 2, int = 2, int = 2002); void print() const; }; void Person::print() const{ cout<<name<<"'s birthday is "; cout<<birthday.month<<"/"<<birthday.day<<"/“ <<birthday.year<<endl; //birthday.print(); //can directly access Date’s private members }

  22. The This Pointer • Every object has access to its own address through a pointer called “this” • Can be used to reference class data members & member functions • Also can be used to enable cascaded member calls

  23. The This Pointer class Fraction { int num, den; public: Fraction(int = 0, int = 1); void print() const; Fraction &multiply(const Fraction &); Fraction &divide(const Fraction &); }; Fraction::Fraction(int n, int d):num(n),den(d){} void Fraction::print() const{ cout << this->num << " / "<< (*this).den <<endl; //reference to data members }

  24. The This Pointer Fraction &Fraction::multiply(const Fraction &f){ num = num * f.num; den = den * f.den; return *this; } Fraction &Fraction::divide(const Fraction &f){ num = num * f.den; den = den * f.num; return *this; } //Enables cascaded member calls (See complete program at this.txt)

  25. The This Pointer int main(){ Fraction f, f1(1,2), f2(2,2), f3(5,2), f4(2,3); f = f1.multiply(f2).multiply(f3).divide(f4); //cascaded member calls //evaluated from left to right f.print(); f1.print(); f2.print(); f3.print(); f4.print(); return 0; } /* 30 / 16 30 / 16 2 / 2 5 / 2 2 / 3 */

  26. Dynamic Memory Allocation • new & delete operators replace C’s malloc & free function calls • new operator • Allocates memory on the heap • Calls the constructor for the object • Returns a pointer to the object on the heap • If the heap if full, new returns 0 • delete operator • Deallocates memory from the heap • Calls the destructor

  27. Dynamic Memory Allocation • Example program (newDelete.txt) int main(){ Fraction *f1; f1 = new Fraction(10); Fraction *f2 = new Fraction(20, 30); Fraction *f3 = new Fraction[40]; f1->print(); // 10/1 f2->print(); // 20/30 f3[39].print(); // 0/1 delete f1; delete f2; delete []f3; return 0; }

  28. Static Class Members • A variable shared by all members of its class • “Class-wide” information • See static.txt class Fraction { int num, den; static int count; public: Fraction(int = 0, int = 1); ~Fraction(); static int getCount(); };

  29. Static Class Members int Fraction::count=0; //initialize static member int Fraction::getCount(){return count;} //accessor function Fraction::Fraction(int n, int d):num(n), den(d){ count++;//constructor increments count } Fraction::~Fraction(){ count--;//destructor decrements count }

  30. int main(){ cout<<"count="<<Fraction::getCount()<<endl; //count=0 Fraction a; { Fraction b; Fraction c; cout<<"count="<<b.getCount()<<endl; //count=3 cout<<"count="<<c.getCount()<<endl; //count=3 } cout<<"count="<<a.getCount()<<endl; //count=1 return 0; }

  31. Class Exercise • Class handout (exercise2.txt)

More Related