Presentation is loading. Please wait.

Presentation is loading. Please wait.

Andy Wang Object Oriented Programming in C++ COP 3330

Similar presentations


Presentation on theme: "Andy Wang Object Oriented Programming in C++ COP 3330"— Presentation transcript:

1 Andy Wang Object Oriented Programming in C++ COP 3330
More about Classes Andy Wang Object Oriented Programming in C++ COP 3330

2 Friends and Members Motivating example
Suppose we want to compare two Fraction objects Fraction f1(1, 2), f2(2,4); If (Equals(f1, f2)) cout << “The fractions are equal\n”;

3 One Possible Solution bool Equals(Fraction x, Fraction y) {
return (x.GetNumerator() * y.GetDenominator() == y.GetNumerator() * x.GetDenominator()); } Need many accessor calls Equals() is not a member function of the Fraction class Not very efficient

4 A More Efficient Way bool Equals(Fraction x, Fraction y) {
return (x.numerator * y.denominator == y.numerator * x.denominator; } However, Equals() does not have access to private data

5 An Alternative—friend
The keyword friend allows a class to grant full access to a function or even another class Access to all the class’s members Including the private section To grant friend status, declare the friend function anywhere in the class declaration A friend function is neither public nor private A friend function is not a member function It is invoked just like a normal function with access to private members

6 Example Fraction Class
ss2/frac1/ Equals() friend function Add() friend function A driver function

7 frac.h class Fraction { friend bool Equals(Fraction x, Fraction y); friend Fraction Add(Fraction x, Fraction y); public: … private: };

8 frac.cpp Note: no keyword friend here
#include <iostream> … bool Equals(Fraction x, Fraction y) { return (x.numerator * y.denominator == y.numerator * x.denominator); } Fraction Add(Fraction x, Fraction y) { int num = x.numerator * y.denominator + y.numberator * x.denominator; int denom = x. denominator * y.denominator; return Fraction(num, denom); Note: no keyword friend here

9 driver.cpp #include <iostream> #include “frac.h” using namespace std; int main() { Fraction f1, f2, f3, f4 cout << “Enter fraction f1: “; f1.Input(); cout << “Enter fraction f2: “; f2.Input(); cout << “\nf1 = “; f1.Show(); cout << “\nf2 = “; f2.Show(); cout << “\n\n”;

10 driver.cpp if (Equals(f1,f2)) cout << “f1 and f2 are equal\n”; else cout << “f1 and f2 are NOT equal\n”; f3 = Add(f1, f2); cout << “f1 + f2 = “; f3.Show(); cout << ‘\n’; return 0; }

11 Another Option Use a member function
if (f1.Equals(f2)) cout << “The fractions are equal\n”; f1 is a calling object f2 is a parameter

12 Equals() Member Function
One possible definition bool Fraction::Equals(Fraction f) { return (numerator * f.GetDenominator() == f.GetNumerator() * denominator); } Another definition return (numerator * f.denominator == f.numerator * denominator); Objects of a class can access each other’s private member data

13 Example http://www.cs.fsu.edu/~myers/cop3330/examples/cla ss2/frac2/
Equals() member function Add() member function Sample driver program

14 frac.h class Fraction { public: … bool Equals(Fraction f);
Fraction Add(Fraction f); private: };

15 frac.cpp include <iostream> …
bool Fraction::Equals(Fraction f) { return (numerator * f.denominator == f.numerator * denominator); } Fraction Fraction::Add(Fraction f) { int num = numerator * f.denominator + f.numberator * denominator; int denom = denominator * f.denominator; return Fraction(num, denom);

16 driver.cpp #include <iostream> #include “frac.h” using namespace std; int main() { Fraction f1, f2, f3, f4; cout << “Enter fraction f1: “; f1.Input(); cout << “Enter fraction f2: “; f2.Input(); cout << “\nf1 = “; f1.Show(); cout << “\nf2 = “; f2.Show(); cout << “\n\n”;

17 driver.cpp if (f1.Equals(f2)) cout << “f1 and f2 are equal\n”; else cout << “f1 and f2 are NOT equal\n”; f3 = f1.Add(f2); cout << “f1 + f2 = “; f3.Show(); cout << ‘\n’; return 0; }

18 Member vs. Friend friend Fraction Add(Fraction f1, Fraction f2);
Parameters are pass-by-value Original objects will not be changed Fraction Add(Fraction f); The private member data of the calling object can be changed

19 Conversion Constructors
Recall that some of the built-in types allow automatic type conversions int x = 5; double y, z; y = x; // legal, via automatic conversion z = x + y; // legal, via automatic conversion Conversion constructor A constructor with one parameter Fraction(int n) converts int to Fraction n/1

20 Explicit and Implicit Conversions
Fraction f1, f2 // create fraction objects; f1 = Fraction(4); // explicit call to conversion constructor f2 = 10; // implicit call to conversion constructor // equivalent to f2 = Fraction(10) f1 = Add(f2, 5); // implicitly converts 5 to Fraction 5/1 Fraction(int n, int d = 1) counts as a conversion constructor Since the second parameter is optional Suppress implicit conversion explicit Fraction(double d); // will NOT be used for // automatic conversions

21 Example ss2/frac3/

22 frac.h class Fraction { public: … Fraction(int n, int d=1);
explicit Fraction(double d); private: };

23 frac.cpp … Fraction::Fraction(int n, int d) { if (SetValue(n, d) == false) SetValue(0,1); } // dummy function // NOT trying to convert d to an equivalent fraction Fraction::Fraction(double d) { SetValue(static_cast<int>(d), 1);

24 driver.cpp … int main() { Fraction f1, f2, f3, f4; f1 = 5; // implicit conversion f2 = Fraction(6); // explicit conversion f3.SetValue(3, 8); f4 = Add(f3, 10); // implicit conversion // same as f2 = Add(f3, Fraction(10))); cout << “\nf1 = “; f1.Show(); cout << “\nf2 = “; f2.Show(); cout << “\nf3 = “; f3.Show(); cout << “\nf4 = “; f4.Show();

25 driver.cpp // f1 = 5.6 // will NOT work f1 = Fraction(5.6) // WILL work return 0; }

26 Using const in Class Specifies what is not allowed to change, within some scope Clarifies the intent of the code to other users Affects how certain items can be used

27 L-Value vs. R-Value L-value = r-value; x = 10 vs. 10 = x?
L-value can appear on the left-hand side of an assignment R-value can appear on the right-hand side of an assignment

28 const Reference Parameters
If an object is passed by value, a copy is made Any R-value can be sent into the call friend Fraction Add(Fraction f1, Fraction f2); If an object is passed by reference (without const), no copy is made Only an L-value can be sent into the call More efficient, especially for large objects However, the object may be changed friend Fraction Add(Fraction &f1, Fraction &f2)

29 const Reference Parameters
If we don’t want to change the original objects, use const reference parameters friend Fraction Add(const Fraction &f1, const Fraction &f2);

30 const Member Functions
void Func(int x) const // const member function Function may NOT change the calling object itself Can ONLY be done to member functions of a class Member function will NOT change the member data of that object Object y will remain the same state before and after this const member function call Yadda y; // object y y.Func(5); // will NOT change the data of y const must go on the declaration and the definition

31 const Member Functions
Should be used whenever appropriate for good class design Constructors initialize the object Would not be const functions Mutators change member data Pure accessor functions retrieve member data Would typically be const functions Functions for printing (e.g., Show(), Display()) Would be good candidates for const functions

32 Examples of friend Functions
ss2/frac4/ Uses const reference parameters on the friend functions Uses const on all member functions that don’t change the member data

33 frac.h class Fraction { friend bool Equals(const Fraction &x, const Fraction &y); friend Fraction Add(const Fraction &x, const Fraction &y); public: Fraction(); Fraction(int n, int d=1); void Input(); void Show() const; int GetNumerator() const; int GetDenominator() const; bool SetValue(int n, int d); double Evaluate() const; private: int numerator, denominator; };

34 frac.cpp … bool Equals(const Fraction &x, const Fraction &y) {…} Fraction Add(const Fraction &x, const Fraction &y) {…} Fraction::Fraction() {…} Fraction::Fractoin(int n, int d) {…} void Fraction::Input() {…} void Fraction::Show() const {…} int Fraction::GetNumerator() const {…} int Fraction::GetDenominator() const {…} bool Fraction::SetValue(int n, int d) {…} double Fraction::Evaluate() const {…}

35 Example with Equals and Add Member Functions
ss2/frac5/ const is used on Add() and Equals(), so that the calling objects will not be changed

36 frac.h class Fraction { public: Fraction(); Fraction(int n, int d=1); void Input(); void Show() const; int GetNumerator() const; int GetDenominator() const; bool SetValue(int n, int d); double Evaluate() const; bool Equals(const Fraction &f) const; Fraction Add(const Fraction &f) const; private: int numerator, denominator; }; Fraction f will not be changed Numerator and denominator will not be changed

37 frac.cpp … bool Fraction::Equals(const Fraction &f) const {…} Fraction Fraction::Add(const Fraction &f) const {…} Fraction::Fraction() {…} Fraction::Fractoin(int n, int d) {…} void Fraction::Input() {…} void Fraction::Show() const {…} int Fraction::GetNumerator() const {…} int Fraction::GetDenominator() const {…} bool Fraction::SetValue(int n, int d) {…} double Fraction::Evaluate() const {…}

38 Declaring const Objects
Need to be initialized at the same line const int SIZE = 10; const double PI = ; Objects can also be declared as const Constructor will be involved An object’s state cannot be changed afterwards const Fraction ZERO; // fixed at 0/1 const Fraction FIXED(3, 4); // fixed at ¾

39 const Objects Can only call const member functions FIXED.Show()
cout << FIXED.Evaluate(); int n = ZERO.GetNumberator(); int d = ZERO.GetDenominator(); Examples of illegal operations (compiler errors) FIXED.SetValue(5, 7); ZERO.Input(); If an object has no constant function (e.g., the earliest Fraction class example), ALL calls will result in compiler errors

40 Example: No const Member Functions
ss2/thing1/ const function calls in main() will not work.

41 thing.h class Thing { public: Thing(); Thing(int h, int w); void Show(); void Set(int h, int w); int GetHeight(); int GetWeight(); private: int height, weight; };

42 thing.cpp #include <iostream> #include “thing.h” using namespace std; Thing::Thing() { height = weight = 0; } Thing::Thing(int h, int w) { height = h; weight = w; } void Thing::Show() { cout << “Height = “ height << “\t\tWeight = “ << weight << ‘\n’; } void Thing::Set(int h, int w) { height = h; weight = w; } Int Thing::GetHeight() { return height; } Int Thing::GetWeight() { return weight; }

43 main.cpp #include <iostream> #include “thing.h” using namespace std; int main() { int temp1, temp2; const Thing t1(4, 100); // all member function calls will fail to compile // since t1 is const t1.Show(); t1.Set(10, 300); temp1 = t1.GetHeight(); temp2 = t1.GetWeight(); return 0; }

44 Example: const Member Functions
ss2/thing2/ const member function calls will compile

45 thing.h class Thing { public: Thing(); Thing(int h, int w); void Show() const; void Set(int h, int w); int GetHeight() const; int GetWeight() const; private: int height, weight; };

46 thing.cpp #include <iostream> #include “thing.h” using namespace std; Thing::Thing() { height = weight = 0; } Thing::Thing(int h, int w) { height = h; weight = w; } void Thing::Show() const { cout << “Height = “ height << “\t\tWeight = “ << weight << ‘\n’; } void Thing::Set(int h, int w) { height = h; weight = w; } Int Thing::GetHeight() const { return height; } Int Thing::GetWeight() const { return weight; }

47 main.cpp #include <iostream> #include “thing.h” using namespace std; int main() { int temp1, temp2; const Thing t1(4, 100); t1.Show(); t1.Set(10, 300); // compilation error temp1 = t1.GetHeight(); temp2 = t1.GetWeight(); return 0; }

48 const Member Data Member data can also be declared const
Tricky syntax Not legal to initialize member data in a class declaration class Thing { public: private: int y = 0; // ILLEGAL const int Z = 10; // ILLEGAL };

49 Another Try thing.h thing.cpp
class Thing { public: … private: int y; const int Z; }; Thing::Thing() { y = 0; Z = 10; // ILLEGAL }

50 Solution Initialization list
return_type function(parameters) : initialization_list { // function body } The initialization list is in the following format const_member_data_1(value_1), const_member_data_2(value_2), …, const_member_data_n(value_n)

51 thing.h class Thing { public: … private: int height, weight; const int LIMIT; static const int SIZE = 10; // static member // shared by all objects of this class };

52 thing.cpp … Thing::Thing() : LIMIT(10) { height = weight = 0; } Thing::Thing(int h, int w) : LIMIT(h) { height = h; weight = w; } void Thing::Set(int h, int w) { if (height > LIMIT) height = LIMIT;

53 main.cpp #include <iostream> #include “thing.h” using namespace std; int main() { int temp1, temp2; Thing t1(12, 100); t1.Show(); cout << “\n”; t1.Set(13, 400); return 0; }

54 Destructors Like constructors, but with a ~ in front
Cannot have parameters Only one destructor per class ~Fraction() Called automatically before an object is deallocated by the system (goes out of scope) Perform clean-up tasks (memory deallocation) before an object is deallocated

55 Example tr1/

56 thing.h class Thing { public: Thing(); Thing(int x); ~Thing(); private: int data; };

57 thing.cpp #include <iostream> #include “thing.h” using namespace std; Thing::Thing() { data = 0; cout << “Running default constructor: data = “ << data << ‘\n’; }

58 thing.cpp Thing::Thing(int x) { data = 0; cout << “Running constructor (with parameter): data = “ << data << ‘\n’; } Thing::~Thing() { cout << “Running destructor: data = “ << data << ‘\n’;

59 main.cpp #include <iostream> #include “thing.h” using namespace std; void Func() { cout << “** Creating object A (local variable in function ** \n”; Thing A(25); }

60 main.cpp int main { cout << “** Declaring object A **\n” Thing A; { cout << “** Declaring B (in new block) **\n”; Thing B(6); cout << “** Calling function Func() **\n”; Func(); cout << “** We have returned from Func() **\n”; cout << “** Leaving local block **\n”; }

61 main.cpp { cout << “** Declaring C (in new block) **\n”; Thing C(10); cout << “** Leaving local block **\n”; } return 0;


Download ppt "Andy Wang Object Oriented Programming in C++ COP 3330"

Similar presentations


Ads by Google