1 / 43

HKUST Summer Programming Course 2008

HKUST Summer Programming Course 2008. Class ~ The essence of Object Oriented Programming. Overview. Difference between struct and class Abstract data type Class components Object Oriented Programming Why object oriented? OOP Features Data Abstraction Encapsulation / Information Hiding

levana
Download Presentation

HKUST Summer Programming Course 2008

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. HKUST SummerProgramming Course 2008 Class ~ The essence of Object Oriented Programming

  2. Overview • Difference between struct and class • Abstract data type • Class components • Object Oriented Programming • Why object oriented? • OOP Features • Data Abstraction • Encapsulation / Information Hiding • Class Declaration and Class Definition

  3. Overview • Class Name: Name Equivalence • Class Data Members • Forward Declaration • Initialization • Class Member Functions • Constant Member Functions • Inline Functions • Member Access Control • How are Objects Implemented? • “this” Pointer • Class Scope and Scope Operator :: • Static Constant Data Member • Class Object Initialization

  4. Difference between struct and class • The only difference between class and struct: • In struct, variables and function are “public” if you don’t specify. • In class, they are “private” by default.

  5. Abstract data type • int, char, double and others are pre-defined data types. On the other hand, class is a user-defined type or an abstract data type. • Variable of a class, is called an “object”. For example, we have a class called Fruit, then we can define an object “apple” of this type. Fruit apple; • Object apple is said to be an “instance” of the Fruit class. Class (Abstract Data Type) Object (Variable)

  6. Class Definition (stack.h) class Stack{ private: int size; // max size of storage int top; // index of the next available space int* data; // data storage public: Stack(int N); // a constructor ~Stack(); // a destructor // basic operations void push(int x); // add another datum int pop(); // get the most recent datum // status operations int num_elements() const; bool empty() const; bool full() const; }; Access Modifiers Data Members Member Functions Remember this semicolon.

  7. Class components • Access modifiers • To control the access right of members inside the class. • Data member • Class member for holding data. • Member function (aka Function Member, Method) • Class member that perform actions on data members. • Constructor • First function to be called when an object is going to be created. Its name is the same as that of the class. • Destructor • Last function to be called when an object is destroying. Its name is the name of the class preceded by a ‘~’.

  8. Object Oriented Programming Concepts

  9. Why object oriented? • For example, const int MAX_ALTITUDE = 11000; const int MAX_SPEED = 960; struct Airplane{ int altitude; int speed; }; void takeoff(Airplane plane); void descend(Airplane plane, int feet);

  10. Max possible speed 0 altitude Why object oriented? • There are some constraints on the Airplane class • Altitude of airplane must be >= 0 but less than some constants (MAX_ALTITUDE). • Not all speeds are possible at all altitudes.

  11. Why object oriented? • Can’t guarantee every access considers these constraints • Altitude and speed are accessible throughout the entire program. • If not all members in a programming team follows the constraints strictly, then logical error will be resulted. • Difficult to debug if the values are found to be wrong. • You need to search over the entire program to fix the bugs.

  12. Why object oriented? • How can constraints be enforced? • We can define a restricted set of functions that access the value of altitude and speed (of Airplane) to ensure data consistency. • Other parts of the program can access the value of altitude and speed only indirectly through this restricted set of functions. • We only have to ensure the constraints be considered in this restricted set of functions (instead of the entire program). • Easier to maintain the code, testing and debugging.

  13. Why object oriented? • How can we ensure that the Airplane structure’s members are only accessed by a restricted set of functions? • In standard procedural programming languages (e.g. C), WE CAN’T ... • This inspired the development of Object-Oriented Programming (OOP) languages, • E.g., C++ and Java

  14. OOP Features • Data abstraction • Encapsulation / Information Hiding • Inheritance (Reusability of code) • Polymorphism • We will discuss the first two features first.

  15. Data Abstraction • A data abstraction is a simplified view of an object. • includes only features one is interested in while hides away the unnecessary details. E.g. • An airplane class is not as complicated as a real plane, it can only let you control the speed and direction of a plane. • In programming languages, a data abstraction becomes an abstract data type or a user-defined type. E.g. Fruit apple; • In OOP, it is implemented as a class.

  16. Encapsulation / Information Hiding • An abstract specification tells us the behavior of an object independent of its implementation. • It tells us what an object does independent of how it works. • Information hiding is also known as data encapsulation, or representation independence. • The principle of information hiding: • Design a program so that the implementation of an object can be changed without affecting the rest of the program. • For example, you can create a stack using linked-list or array. That will not affect the stack’s public interface. • A stack should support “push” and “pop”

  17. Classes and Programming • Conceptually a class is a blueprint or a design of something. • When we create a product according to this blueprint, that is an object. • E.g. to build five cars according to a Car blueprint • Although “object oriented” is a way to simulate our concepts in real-world, we can’t forget its “programming” part. • That means a class should have its own functions, data structures, data types, etc. • We have to learn a lot of syntax and special behavior of C++ in order to carry out those object oriented concepts.

  18. Class Declaration and Class Definition • As in function, we can introduce the name of a class, without defining it • Class Definition • Define what a class contains • What is its data member and member functions • Including the type of data members and the declaration of member functions • Class Declaration • Introduce a class name only • Usage will be covered later • Class Implementation • Include all definition of the member functions

  19. Header file (stack.h) class Stack; // class declaration class Stack{ // class definition private: int size; // max size of storage int top; // index of the next available space int* data; // data storage public: Stack(int N); // declaration of constructor ~Stack(); // declaration of a destructor void push(int x); // declaration of a member function int pop(); int num_elements() const; bool empty() const; bool full() const; };

  20. Source file (stack.cpp) #include “stack.h” // remember to include the header file // class implementation (defines all member functions) Stack::Stack(int N) { size = N; top = 0; data = new int[size]; } Stack::~Stack(){ delete [] data; data = NULL; } void Stack::push(int x){ if ( full() ) cout << “ERROR: Stack is already full” << endl; else data[top++] = x; }

  21. Source file (stack.cpp) […continue] int Stack::pop(){ if ( empty() ){ cout << “ERROR: Stack is empty” << endl; return -9999; } return data[--top]; } int Stack::num_elements() const{ return top; } bool Stack::empty() const{ return ( top == 0 ); } bool Stack::full() const{ return ( top == size ); }

  22. Class Name: Uniqueness • The name of classes cannot be used in two definitions. class W { int a; }; // error, double class W { double b; }; // definition // OK, a class can be declared multiple times class R; // class declaration class R { int a; }; // class definition class R; // OK: another declaration

  23. Class Name: Name Equivalence • A class definition introduces a new abstract data type. C++ relies on name equivalence (and NOT structure equivalence) for class types. class X { int a; }; // define two different classes class Y { int a; }; // with same structure X x; // create two objects for class X and Y Y y; x = y; // error: type mismatch; x and y are objects // of different types

  24. Class Data Members • Data members can be of a pointer or reference of its own type: class A { A* pointerA; A& refA; A objA; // ERROR: cannot use its own type, except // pointer/reference }; • Using objA inside the definition of class A makes the size of object infinite, therefore it is not allowed. • However, pointer and reference must occupy 4 bytes only. It is allowed in the definition of class A.

  25. Class Data Members - Forward Declaration • Data members of a class can be of any basic type, or any user-defined type if they are declared/defined: • A forward declaration for class pointers: class Cell; // forward declaration of Cell class class Stack { int size; Cell *top; // OK: because we declared that there is // a Cell class (forward declaration) Cell x; // Error: the definition of Cell class // is not complete! }; class Cell { int a; }; class Stack{ Cell x; }; // OK, Cell is already defined

  26. Class Data Members - Necessity of Forward Declaration • Recursively uses user-defined type in class definition class A; // forward declaration class B{ // definition of class B A* pointerA; }; class A{ // definition of class A B* pointerB; B objB; // this is also allowed };

  27. Class Data Members - Initialization • Data members can NOT be initialized (give initial values) inside the class definition. class Stack { // ... int top = 0; // Error: class data member // cannot be initialized here }; • Initialization should be done with appropriate constructors, or member functions. Stack::Stack(int N) { // constructor definition top = 0; // It is ok }

  28. Class Member Functions • These are the functions declared inside the body of a class, but they can be defined in two ways: • Within the class body, they are inline functions class Stack { // ... void push(int x) { /* ... */ } int pop() { /* ... */ } }; • Outside the class body class Stack { // ... void push(int x); int pop(); }; void Stack::push(int x) { /* ... */ } int Stack::pop() { /* ... */ }

  29. Constant Member Functions • ‘const’ keyword can guarantee that the member function won’t modify the invoking object. class Stack { … int num_elements() const { return size; } // OK int pop() const { --top; return top; } // ERROR }; • To define a function outside the class int Stack::num_elements() const { return size; }

  30. Constant Member Functions • Also, for a constant object, it can call its constant member functions only. • Calling constructor and destructor are exceptions, because they can’t be declared as constant functions. Stack stk_a; const Stack stk_b; stk_a.num_elements(); // OK stk_b.num_elements(); // OK stk_a.pop(); // OK stk_b.pop(); // ERROR: constant object // accesses non-const member

  31. Inline Functions • Member function can also be inlined class Stack{ // ... int num_elements() const { return top; } }; int main() { Stack stackA; cout << stackA.num_elements() << endl; return 0; } • The above cout statement is similar to cout << stackA.top << endl;

  32. Inline Functions • On the other hand, when you define a member function inside the class, it is automatically treated as an inline function. class Stack { // ... // define the member function inline int num_elements() const { /* ... */ } int pop() { /* ... */ } };

  33. Inline Functions • To enhance readability, you may also define inline functions in the same header file with the class but outside the class definition. // Stack.h class Stack { … inline void push(int x); // an inline function }; // put the inline function out of the class inline void Stack::push(int x) { top = x; ++top; }

  34. Inline Functions • Recall that C++ compilers may NOT honor your inline declaration. • The inline declaration is just a hint to the compiler. • Compiler still has the freedom to choose whether to inline your function or not, especially when the function is large.

  35. How are objects implemented? • Each class object gets its own copy of the data members. • All objects of the same class share one copy of the member functions. int main() { Stack x(2), y(3); x.push(1); y.push(2); y.pop(); }

  36. Member Access Control • A member (data or function) of a class can be: • public : accessible to anybody (inside or outside the class). • private : accessible only to member functions (include another object of the same class). It is mainly used to enforce information hiding. class A { private: int x; public: A() { x = 3; } // initialize x to 3 void add(A another) { x = another.x + x; } // it is ok to access another object of the // same class. Not prohibited by private. }; • protected: it will be discussed later.

  37. Accessing Member Functions / Data Members • Use member access operator (.) Stack stackA(12); stackA.push(3); // call a member function // in Stack class • Use dereference member access operator (->) // a pointer to a Stack object Stack* stackA = new Stack(12); stackA->push(3); • It is equal to a deference operator plus a member access operator, i.e. (*stackA).push(3); • You can also use these operators to access the data members

  38. “this” Pointer • Each class member function implicitly contains a pointer of its class type named “this”. • When an object calls the function, this pointer is set to point to the invoking object. • For example, the C++ compiler developed by AT&T Bell Labs will automatically translate the function void Stack::push(int x) in the class Stack to a unique global function by adding a new argument: void Stack::push(Stack* this, int x) { if ( this->full() ) cout << “ERROR: Stack is already full” << endl; else this->data[ (this->top)++ ] = x; } • a.push(x) becomes push(&a, x).

  39. “this” Pointer of constant member function • Since a constant member function cannot modify the data members, the “this” pointer is declaraed as a constant pointer type void Stack::num_elements(const Stack* this) { return top; // return this->top; // equivalent }

  40. Necessity of using “this” Pointer • Return an object by “this”. class Complex { private: float real; float imag; public: // Addition of complex numbers Complex add( const Complex& x) { real += x.real; imag += x.imag; return *this; // return the object itself } }; • Use the above code, we can do something like this Complex x, y, z; // ... Complex a = z.add( x.add(y) );

  41. Class Scope and Scope Operator :: • C++ statically binds name occurrences to declarations at compile time int height; // global “height” class Hill { int height; // local “height” Hill() { height = 0; } // constructor }; • Which “height” does Hill() using? • Hill::height (the one defined in the class Hill) • How to access the global “height” inside class Hill? • ::height

  42. Class Scope and Scope Operator :: #include <iostream> using namespace std; int height; class Hill { private: int height; public: Hill() { // constructor ::height = 0; // Access global “height” using :: height = 7; // Access local “height” } void print() {cout << "local height " << height << endl; } }; void main() { Hill h; h.print(); cout << "global height " << height << endl; }

  43. Constant Data Member • Sometimes, a data member should not be changed after the object has been constructed. class Airplane { private: const string MODEL_NUMBER; int altitude; int speed; public: Airplane(string modelNumber, int altitude, int speed); void takeoff(Airplane plane); void descend(Airplane plane, int feet); void print() const; };

More Related