800 likes | 956 Views
CS2311 Computer Programming. Dr. Yang, QingXiong (with slides borrowed from Dr. Yuen, Joe) LT7: Class and Objects. Outline. Defining classes Defining member functions & scope resolution operator Public & private members Accessors Constructors Friend functions Const modifier
E N D
CS2311 Computer Programming Dr. Yang, QingXiong (with slides borrowed from Dr. Yuen, Joe) LT7: Class and Objects
Outline • Defining classes • Defining member functions & scope resolution operator • Public & private members • Accessors • Constructors • Friend functions • Const modifier • Operator overloading • C-like Structure
Class and Object • Class and object are important features of Object-oriented Programming Language (like C++, Java, C#) • With class, variables and their directly related functions can be grouped together to form a new data type • It promotes reusability and object-oriented design (not covered in this course) • Object is an instance of class, i.e. class is a blue-print and its product is its object.
Class and Object : Example Without class/object With class/object int radius; int width, height; double getCircleArea(){ return 3.14*radius*radius; } double getRectangleArea(){ return width*height; } double getCirclePerimeter(){ return 2*3.14*radius; } double getRectanglePerimeter(){ return 2*(width+height); } class Circle { public: int radius; double getCircleArea(){ return 3.14*radius*radius; } double getCirclePerimeter(){ return 2*3.14*radius; } } class Rect{ public: int width, height; double getRectangleArea(){ return width*height; } double getRectanglePerimeter(){ return 2*(width+height); } }
Class and Object void main(){ cout << “Please enter the radius of circle”; cin >> radius; cout << getCircleArea(); cout << “Please enter the width and height of a rectangle”; cin >> width >> height; cout << getRectangleArea(); } Without class/object void main(){ Rect r; //Rect is a class, r is an object of Rect Circle c; cout << “Please enter the radius of circle”; cin >> c.radius; cout << c.getCircleArea(); cout << “Please enter the width and height of a rectangle”; cin >> r.width >> r.height; cout << r.getRectangleArea(); } With class/object
Class in Computer Programming • An abstract view of real-world objects, e.g. car, horse • Computer program is a model of real-world problem • Simple problem: program with variables and functions • Large scale program: class and object • Class: • definition of program component • consists of member variables and member functions • Member variable : variable belong to class • Member function: function primary designed to access/manipulate the member variable of the class • Object: • An instance of class / runtime representation of a class
Class in programming Class:Robot void start(); void shutdown(); void moveForward(int step); void turnLeft(int degree); void turnRight(int degree); void takePhoto(); ………………………………….. intmodelNum; int width; int height; intpowerLevel; …………………… Member variable Member functions
What is an object? Objects of Circle Class: Circle Radius:10 Color:orange int radius; int color; Radius:15 Color: blue Member functions Radius:12 Color: green
Classes and Objects in C++ • A class is a data type, objects are variables of this type • An object is a variable with member functions and data values • cin, cout are objects defined in header <iostream> • C++ has great facilities for you to define your own class and objects
Defining classes class class_name{ public / protected / private: attribute1 declaration; attribute1 declaration; method1 declaration; method2 prototype; }; return_valueclassname::method2{ method body statement; }
Defining classes (example I) #include <iostream> using namespace std; class DayOfYear { public: intmonth; int day; void output(){ cout<< "month =" << month; cout << ", day =" << day << endl; } }; Member variables Member function
Member function – Declare and Define • In C++, a class definition commonly contains only the prototypes of its member functions (except for inline functions) • Use classname::functionName to define the member function (method) of particular class. class Circle { …… int radius; …… double getArea(); } double Circle::getArea(){ return 3.1415*radius*radius; }
Defining classes (example II) #include <iostream> using namespace std; class DayOfYear { public: void output(); //member func. prototype int month; int day; }; void DayOfYear::output() { cout << "month =" << month << ", day =" << day << endl; } Define the method elsewhere
Main function void main() { DayofYear today, birthday; cin >> today.month >> today.day; cin >> birthday.month >> birthday.day; cout << "Today’s date is: "; today.output(); cout << "Your birthday is: "; birthday.output(); if (today.month == birthday.month && today.day == birthday.day) cout << "Happy Birthday!\n"; }
Create object and access its member function • To declare an object of a class Class_namevariable_name; Examples: Circle c1,c2; DayofYear today; • A member function of an object is called using the dot operator: • today.output(); • c1.getArea();
Public and private members • By default, all members of a class are private • You can declare public members using the keyword public • Private members can be accessed only by member functions (and friend functions) of that class, i.e. only from within the class, not from outside
A new class definition for DayOfYear class DayOfYear { public: void input(); void output(); void set(intnew_m, intnew_d); intget_month(); intget_day(); private: bool valid(int m, int d); // check if m,d valid int month; int day; };
Member function definitions void DayOfYear::input() { int m, d; // input and validate do { cout << "Enter month and day as numbers: "; cin >> m >> d; // local var. of input() } while (!valid(m,d)); month = m; // accessing private members day = d; }
Member function definitions (cont'd) void DayOfYear::set(intnew_m, intnew_d) { if (valid(new_m, new_d)) { month = new_m; day = mew_d; } } intDayOfYear::get_month() { return month; } intDayOfYear::get_day() { return day; }
Member function definitions (cont'd) bool DayOfYear::valid(int m, int d) { if (m<1 || m>12 || d<1) return false; switch(m){ case 1: case 3: case 5: case 7: case 8: case 10: case 12: return d<=31; break; case 4: case 6: case 9: case 11: return d<=30; break; case 2: return d<=29; break; } }
A new main program void main() { DayOfYear today, birthday; today.input(); birthday.input(); cout << "Today’s date is:\n"; today.output(); cout << “Your birthday is:\n”; birthday.output(); if (today.get_month()==birthday.get_month() && today.get_day() == birthday.get_day()) cout << “Happy Birthday!\n”; }
Private Variable and Access functions • Member functions that give you access to the values of the private member variables are called access functions, e.g., get_month, set • Useful for controlling access to private members: • E.g. Provide data validation to ensure data integrity. • Needed when testing equality of 2 objects. (The predefined equality operator = = does not work for objects and variables of structure type.), e.g. obj1==obj2 (not work!)
Why private variable? • Prevent others from accessing the variables directly, i.e. variables can be only accessed by access functions. class DayOfYear { ……… private: intmonth; intday; ……… }; void DayOfYear::set(intnew_m, intnew_d) { …… month = new_m; day = mew_d; …… } intDayOfYear::get_month() { return month; } intDayOfYear::get_day() { return day; }
Why private variable? • Change of the internal presentation, e.g. variable name, type, will not affect the how the others access the object. Caller still calling the same function with same parameters void DayOfYear::set(intnew_m, intnew_d) { …… m = new_m; d = mew_d; …… } intDayOfYear::get_month() { return m; } intDayOfYear::get_day() { return d; } class DayOfYear { ……… private: int m; int d; ……… };
Why private members? • The common style of class definitions • To have all member variables private • Provide enough access functions to get and set the member variables • Supporting functions used by the member functions should also be made private • Only functions that need to interact with the outside can be made public
Assignment operator for objects • It is legal to use assignment operator = with objects or with structures • E.g. DayOfYeardue_date, tomorrow; tomorrow.input(); due_date = tomorrow; • This effectively makes both variables pointing to the same memory address of the object
Constructors for initialization • Class contains variables and functions • Variables must be initialized before use • In C++, a constructor is designed to initialize variables • A constructor is a member function that is automatically called when an object of that class is declared • Special rules: • A constructor must have the same name as the class • A constructor definition cannot return a value
Example: Bank account • E.g., Suppose we want to define a bank account class which has member variables balance and interest_rate. We want to have a constructor that initializes the member variables. class BankAcc { public: BankAcc(int dollars, int cents, double rate); ... private: double balance; double interest_rate; }; ... BankAcc::BankAcc(int dollars, int cents, double rate) { balance = dollars + 0.01*cents; interest_rate = rate; }
Constructors • When declaring objects of BankAcc class: BankAcc account1(10,50,2.0), account2(500,0,4.5); • Note: A constructor cannot be called in the same way as an ordinary member function is called: account1.BankAcc(10,20,1.0); // illegal
Constructors • More than one versions of constructors are usually defined (overloaded) so that objects can be initialized in more than one way, e.g. class BankAcc { public: BankAcc(int dollars, int cents, double rate); BankAcc(int dollars, double rate); BankAcc(); ... private: double balance; double interest_rate; };
Constructors BankAcc::BankAcc(int dollars, int cents, double rate) { balance = dollars + 0.01*cents; interest_rate= rate; } BankAcc::BankAcc(int dollars, double rate) { balance = dollars; interest_rate= rate; } BankAcc::BankAcc() { balance = 0; interest_rate= 0.0; }
Constructors • When the constructor has no arguments, don’t include any parentheses in the object declaration. • E.g. BankAcc acc1(100, 50, 2.0), // OK acc2(100, 2.3), // OK acc3(), // error acc4; // correct • The compiler thinks that it is the prototype of a function called acc3 that takes no arguments and returns a value of type BankAcc
Constructors • Alternative way to call a constructor: obj = constr_name(arguments); E.g.,BankAcc account1; account1 = BankAcc(200, 3.5); • Mechanism: calling the constructor creates an anonymous object with new values; the object is then assigned to the named object • A constructor behaves like a function that returns an object of its class type
Default constructors • A constructor with no parameters • Will be called when no argument is given • It does nothing at all! class Circle{ int radius; Circle(); double getArea(); }; void Circle:: Circle(){ radius=0; } double Circle::getArea(){ return 3.1415*radius; } void main(){ Circlecircle; circle.getArea(); }
Default constructors • Default constructor will be generated by compiler automatically if NO constructor is defined so far. • However, if any non-default constructor is defined, call the default constructor will have compilation error. class Circle{ int radius; circle(int r); double getArea(); }; Circle::Circle(int r){ radius=r; } double Circle::getArea(){ return 3.1415*radius; } void main(){ Circlecircle; //illegal Circle circle(6); //OK circle.getArea(); }
Parameters Passing: Call-by-Reference • Parameters pass to a function can be updated inside the function • Add ‘&’ in font of the parameter that to be called by reference • More detail will be given in further Lecture (Pointer) void swap(int&a, int&b){ int temp; temp=a; a=b; b=temp; } void main(){ int x=1,y=3; cout << “x:”<<x <<“,y:”<<y<<endl; swap(x,y); cout << “x:”<<x <<“,y:”<<y<<endl; }
Friend Function • Not all functions could logically belong to a class, and sometimes, it is more natural to implement an operation as ordinary (nonmember) functions, • e.g. Equality (==) function that test if 2 objects are equal • Equality operator == cannot be applied directly on objects or structures • Defining it as a member function will lose the symmetry • It is more natural to define such function as an ordinary (nonmember) function
Equalitytesting: ordinary function #include <iostream> using namespace std; class Rectangle { public: Rectangle(intw,int h); intgetArea(); intgetWidth(); intgetHeight(); private: int width; int height; }; Rectangle::Rectangle(intw,int h){ width=w; height=h; } int Rectangle::getWidth(){ return width; } int Rectangle::getHeight(){ return height; } int Rectangle::getArea(){ return width*height; }
Equalitytesting: ordinary function bool equal(Rectangle r1, Rectangle r2){ if (r1.getWidth()==r2.getWidth() && r1.getHeight()==r2.getHeight()) return true; else return false; } void main() { Rectangle ra(10,22), rb(10,21); if ( equal(ra, rb) ) cout << “They are the same\n"); }
Friend function • The previous equality function needs to call access functions several times not efficient • However, declare the member variable as public and direct access them are not recommend class Rectangle { public: intwidth,height; …… } bool equal(Rectangle r1, Rectangle r2){ if (r1.width ==r2.width && r1.height==r2.height) return true; else return false; }
Friend function • Solution: Define a friend function! • A friend function of a class is nota member function of the class but has access to the private members of that class • A friend function doesn’t need to call access functions more efficient • Also the code looks simpler • A friend function will be public no matter it is defined under “public:” or not
Equalitytesting: friend function #include <iostream> using namespace std; class Rectangle { public: Rectangle(intw,int h); friend bool equal(Rectangle r1,Rectangle r2); intgetArea(); intgetWidth(); intgetHeight(); private: int width; int height; }; Rectangle::Rectangle(intw,int h){ width=w; height=h; } int Rectangle::getWidth(){ return width; } int Rectangle::getHeight(){ return height; }
Equalitytesting: friend function /*Note the friend function is not implemented in Rectangle class*/ bool equal(Rectangle r1, Rectangle r2){ if (r1.width ==r2.width && r1.height==r2.height) return true; else return false; } void main() { Rectangle ra(10,22), rb(10,21); if ( equal(ra, rb) ) cout << “They are the same\n"); }
constmodifier revisited • By default, parameters passed to a functioncould be call-by-value or call-by-reference mechanism • Call-by-value: a copy of variable is passed. • Call-by-reference: the original data, not the copy is passed to a function • In call-by-reference, if the function is not supposed to change the value of the parameter, you can mark it with a const modifier • The compiler will then complain when you modify it by mistake
constmodifier revisited • Call-by-reference: • the original data, not the copy is passed to a function • Add ‘&’ before the parameter name in function prototype and definition. class Rectangle {…… friend bool equal(Rectangle &r1,Rectangle &r2); …… }; bool equal(Rectangle &r1, Rectangle &r2){ if (r1.width ==r2.width && r1.height==r2.height) …… }
constparameter modifier class Circle { int radius; public: Circle(int r); void set(Circle &c); double getArea(); }; Circle::Circle(int r){ radius=r; } void Circle::set(Circle &c){ radius=c.radius; } double Circle::getArea(){ return 3.14*radius*radius; } void main(){ Circle c1(3); Circle c2(5); cout << c1.getArea(); cout << '=‘; cout << c2.getArea(); cout << endl; c2.set(c1); cout << c1.getArea(); cout << '=‘; cout << c2.getArea(); cout << endl; }
constparameter modifier class Circle { int radius; public: Circle(int r); void set(Circle &c); double getArea(); }; Circle::Circle(int r){ radius=r; } void Circle::set(Circle &c){ c.radius=radius; } double Circle::getArea(){ return 3.14*radius*radius; } void main(){ Circle c1(3); Circle c2(5); cout << c1.getArea(); cout << '=‘; cout << c2.getArea(); cout << endl; c2.set(c1); cout << c1.getArea(); cout << '=‘; cout << c2.getArea(); cout << endl; }
constparameter modifier class Circle { int radius; public: Circle(int r); void set(const Circle &c); double getArea(); }; Circle::Circle(int r){ radius=r; } void Circle::set(const Circle &c){ c.radius=radius; } double Circle::getArea(){ return 3.14*radius*radius; } void main(){ Circle c1(3); Circle c2(5); cout << c1.getArea(); cout << '=‘; cout << c2.getArea(); cout << endl; c2.set(c1); cout << c1.getArea(); cout << '=‘; cout << c2.getArea(); cout << endl; } Compile will complain!
constmodifier for function • When you have a call to a member, the calling object behaves like a call-by-reference parameter: C1.getArea(); • That function may change the value of the calling object double Circle::getArea(){ return 3.1415*radius*radius++; } • If you have a member function that is not supposed to change the calling object, you can add the constmodifier after the function name (both prototype and definition) double getArea() const; double Circle::getArea() const{…..