600 likes | 618 Views
Review. Characteristics of OOPL Templates Standard Template Library. C haracteristics of OOPL. Encapsulation = combining data structure with actions - actions -> permissible behaviors of objects that are controlled through the member functions
E N D
Review Characteristics of OOPL Templates Standard Template Library
Characteristics of OOPL • Encapsulation=combining data structure with actions -actions -> permissible behaviors of objects that are controlled through the member functions -data structure -> represents the properties, the state, or characteristics of objects -information hiding= process of making certain items inaccessible • Inheritance=ability to derive new objects from old -permits objects of a more specific class to inherit the properties (data) and behaviors (functions) of a more general class -ability to define a hierarchical relationship between objects • Polymorphism=how objects respond to certain kinds of messages -ability for different objects to interpret functions differently
Class Classes & Objects • The class is the cornerstone of C++ • It gives the C++ its identity from C • It makes possible encapsulation, data hiding and inheritance • Class: • Consists of both data and methods • Defines properties and behavior of a set of entities • Object: • An instance of a class • A variable identified by a unique name
Header Body ClassDefine a Class Type class class_name { permission_label: member; permission_label: member; ... }; class Rectangle { private: int width; int length; public: void set(int w, int l); int area(); };
ClassClass Definition-Data Members • Abstract the common attributes of a group of entities, their values determine the state of an object • Can be of any type, built-in or user-defined • non-static data member • Each class object has its own copy • Cannot be initialized explicitly in the class body • Can be initialized with member function, or class constructor • static data member • Acts as a global object, part of a class, not part of an object of that class • One copy per class type, not one copy per object • Can be initialized explicitly in the class body
ClassClass Definition – Member Functions • Used to • access the values of the data members (accessor) • perform operations on the data members (implementor) • Are declared inside the class body, in the same way as declaring a function • Their definition can be placed inside the class body, or outside the class body • Can access both public and private members of the class • Can be referred to using dot or arrow member access operator
class name member function name inline scope operator ClassDefine a Member Function class Rectangle { private: int width, length; public: void set (int w, int l); int area() {return width*length; } } void Rectangle :: set (int w, int l) { width = w; length = l; } r1.set(5,8); rp->set(8,10);
ClassClass Definition – Member Functions • static member function • const member function • declaration • return_typefunc_name (para_list) const; • definition • return_typefunc_name (para_list) const { … } • return_typeclass_name :: func_name (para_list) const { … } • Makes no modification about the data members (safe function) • It is illegal for a const member function to modify a class data member
ClassClass Definition - Access Control • Information hiding • To prevent the internal representation from direct access from outside the class • Access Specifiers • public • may be accessible from anywhere within a program • Private (default) • may be accessed only by the member functions, and friends of this class, not open for nonmember functions • protected • acts as public for derived classes (virtual) • behaves as private for the rest of the program • Difference between classes and structs in C++ • the default access specifier is private in classes • the default access specifier ispublic in structs
ObjectDeclaration class Rectangle { private: int width; int length; public: void set(int w, int l); int area(); } main() { Rectangle r1; Rectangle r2; r1.set(5, 8); cout<<r1.area()<<endl; r2.set(8,10); cout<<r2.area()<<endl; }
ObjectDeclaration r1 is statically allocated class Rectangle { private: int width; int length; public: void set(int w, int l); int area(); } main() { Rectangle r1; r1.set(5, 8); } r1 width length width = 5 length = 8
5000 r1 width length width = 5 length = 8 ObjectDeclaration r2 is a pointer to a Rectangle object class Rectangle { private: int width; int length; public: void set(int w, int l); int area(); } main() { Rectangle r1; r1.set(5, 8); Rectangle *r2; r2 = &r1; r2->set(8,10); } //dot notation //arrow notation r2 width = 8 length = 10 6000 ??? 5000
r3 6000 5000 ??? 5000 ??? width length ObjectDeclaration r3 is dynamically allocated class Rectangle { private: int width; int length; public: void set(int w, int l); int area(); } main() { Rectangle *r3; r3 = new Rectangle(); r3->set(80,100); delete r3; r3 = NULL; } //arrow notation NULL width = 80 length = 100
Object Initialization 1. By Assignment #include <iostream.h> class circle { public: double radius; }; • Only work for public data • members • No control over the operations • on data members int main() { circle c1;// Declare an instance of the classcircle c1.radius = 5;// Initialize by assignment }
Object Initialization #include <iostream.h> class circle { private: double radius; public: void set (double r) {radius = r;} double get_r () {return radius;} }; 2. By Public Member Functions • Accessor • Implementor int main(void) { circle c; // an object of circle class c.set(5.0); // initialize an object with a publicmember function cout << "The radius of circle c is " << c.get_r() << endl; // access a private data member with an accessor }
They are publicly accessible Have the same name as the class There is no return type Are used to initialize class data members They have different signatures Object Initialization 3. By Constructor class Rectangle { private: int width; int length; public: Rectangle(); Rectangle(const Rectangle &r); Rectangle(int w, int l); void set(int w, int l); int area(); } • Default constructor • Copy constructor • Constructor with parameters
Object Initialization • Initialize with default constructor class Rectangle { private: int width; int length; public: void set(int w, int l); int area(); } Rectangle r1; Rectangle *r3 = new Rectangle(); • Initialize with copy constructor Rectangle r4; r4.set(60,80); Rectangle r5 = Rectangle(r4); Rectangle *r6 = new Rectangle(r4);
5000 r7 width length width = 20 length = 50 6000 ??? 5000 Object Initialization Write your own constructors class Rectangle { private: int width; int length; public: Rectangle(); Rectangle(int w, int l); void set(int w, int l); int area(); } Rectangle :: Rectangle() { width = 20; length = 50; }; Rectangle *r7 = new Rectangle();
ObjectCleanup Destructor class Account { private: char *name; double balance; unsigned int id; //unique public: Account(); Account(const Account &a); Account(const char *person); ~Account(); } Account :: ~Account() { delete[] name; release_id (id); } • Its name is the class name preceded by a ~ (tilde) • It has no argument • It is used to release dynamically allocated memory and to perform other "cleanup" activities • It is executed automatically when the object goes out of scope
Define a Class Hierarchy • Syntax: classDerivedClassName : access-levelBaseClassName where • access-level specifies the type of derivation • private by default, or • public • Any class can serve as a base class • Thus a derived class can also be a base class
Access Rights of Derived Classes Type of Inheritance • The type of inheritance defines the minimum access level for the members of derived classthat are inherited from the base class • With public inheritance, the derived class follow the same access permission as in the base class • With protected inheritance, the public and the protected members inherited from the base class can be accessed in the derived class as protected members • With private inheritance, none of the members of base class is accessible by the derived class Access Control for Members
What to inherit? • In principle, every member of a base class is inherited by a derived class • just with different access permission • However, there are exceptions for • constructor and destructor • operator=() member • friends Since all these functions are class-specific
Constructor Rules for Derived Classes The default constructor and the destructor of the base class are always called when a new object of a derived class is created or destroyed. class A { public: A ( ) {cout<< “A:default”<<endl;} A (int a) {cout<<“A:parameter”<<endl;} } class B : public A { public: B (int a) {cout<<“B”<<endl;} } output: A:default B B test(1);
Constructor Rules for Derived Classes You can also specify an constructor of the base class other than the default constructor • DerivedClassCon ( derivedClass args ) : BaseClassCon ( baseClass args ) • { DerivedClass constructor body } class A { public: A ( ) {cout<< “A:default”<<endl;} A (int a) {cout<<“A:parameter”<<endl;} } class C : public A { public: C (int a) : A(a) {cout<<“C”<<endl;} } output: A:parameter C C test(1);
Define its Own Members The derived class can also define its own members, in addition to the members inherited from the base class class Point{ protected: int x, y; public: void set(int a, int b); } x y Point x y r Circle protected: int x, y; private: double r; public: void set(int a, int b); void set_r(double c); class Circle : public Point{ private: double r; public: void set_r(double c); }
Overriding • A derived class can override methods defined in its parent class. With overriding, • the method in the subclass has the identical signature to the method in the base class. • a subclass implements its own version of a base class method. class A { protected: int x, y; public: void print () {cout<<“From A”<<endl;} } class B : public A { public: void print () {cout<<“From B”<<endl;} }
Operator overloading • Programmer can use some operator symbols to define special member functions of a class • Provides convenient notations for object behaviors
Implementing Operator Overloading • Two ways: • Implemented as member functions • Implemented as non-member or Friend functions • the operator function may need to be declared as a friend if it requires access to protected or private data • Expression obj1@obj2 translates into a function call • obj1.operator@(obj2), if this function is defined within class obj1 • operator@(obj1,obj2), if this function is defined outside the class obj1
c = a.operator+ (b); Implementing Operator Overloading • Defined as a member function class Complex { ... public: ... Complex operator +(const Complex &op) { double real = _real + op._real, imag = _imag + op._imag; return(Complex(real, imag)); } ... }; c = a+b;
c = operator+ (a, b); Implementing Operator Overloading • Defined as a non-member function class Complex { ... public: ... double real() { return _real; } //need access functions double imag() { return _imag; } ... }; c = a+b; Complex operator +(Complex &op1, Complex &op2) { double real = op1.real() + op2.real(), imag = op1.imag() + op2.imag(); return(Complex(real, imag)); }
c = operator+ (a, b); Implementing Operator Overloading • Defined as a friend function class Complex { ... public: ... friend Complex operator +( const Complex &, const Complex & ); ... }; c = a+b; Complex operator +(Complex &op1, Complex &op2) { double real = op1._real + op2._real, imag = op1._imag + op2._imag; return(Complex(real, imag)); }
Polymorphism – An Introduction • Definition • noun, the quality or state of being able to assume different forms - Webster • An essential feature of an OO Language • It builds upon Inheritance • Allows run-time interpretation of object type for a given class hierarchy • Also Known as “Late Binding” • Implemented in C++ using virtual functions
Polymorphism – An Introduction • Polymorphism is built upon class inheritance • It allows different versions of a function to be called in the same manner, with some overhead • Polymorphism is implemented with virtual functions, and requires pass-by-reference
Virtual Functions • Virtual Functions overcome the problem of run time object determination • Keyword virtualinstructsthe compiler to use late binding and delay the object interpretation • How ? • Define a virtual function in the base class. The word virtual appears only in the base class • If a base class declares a virtual function, it must implement that function, even if the body is empty • Virtual function in base class stays virtual in all the derived classes • It can be overridden in the derived classes • But, a derived class is not required to re-implement a virtual function. If it does not, the base class version is used
Abstract Classes & Pure Virtual Functions • Some classes exist logically but not physically. • Example : Shape • Shape s; // Legal but silly..!! : “Shapeless shape” • Shape makes sense only as a base of some classes derived from it. Serves as a “category” • Hence instantiation of such a class must be prevented class Shape //Abstract {public ://Pure virtual Functionvirtual void draw() = 0; } • A class with one or more pure virtual functions is an Abstract Class • Objects of abstract class can’t be created Shape s; // error : variable of an abstract class
Function Template • A C++ language construct that allows the compiler to generate multiple versions of a function by allowing parameterized data types. FunctionTemplate Template < TemplateParamList > FunctionDefinition TemplateParamDeclaration: placeholder class typeIdentifier typename variableIdentifier
Instantiating a Function Template • When the compiler instantiates a template, it substitutes the template argument for the template parameter throughout the function template. TemplateFunction Call Function < TemplateArgList > (FunctionArgList)
Class Template • A C++ language construct that allows the compiler to generate multiple versions of a class by allowing parameterized data types. Class Template Template < TemplateParamList > ClassDefinition TemplateParamDeclaration: placeholder class typeIdentifier typename variableIdentifier
Instantiating a Class Template • Class template arguments must be explicit. • The compiler generates distinct class types called template classes or generated classes. • When instantiating a template, a compiler substitutes the template argument for the template parameter throughout the class template.
Instantiating a Class Template To create lists of different data types // Client code GList<int> list1; GList<float> list2; GList<string> list3; list1.Insert(356); list2.Insert(84.375); list3.Insert("Muffler bolt"); template argument Compiler generates 3 distinct class types GList_int list1; GList_float list2; GList_string list3;
Function Definitions for Members of a Template Class template<class ItemType> void GList<ItemType>::Insert( /* in */ ItemType item ) { data[length] = item; length++; } //after substitution of float void GList<float>::Insert( /* in */ float item ) { data[length] = item; length++; }
Another Template Example: passing two parameters template <class T, int size> class Stack {... T buf[size]; }; Stack<int,128> mystack; non-type parameter
Indicating Typename • In a template, the name of a member of another class that depends on its template parameter(s) (first<T>::pointer in this example, dependent on the T parameter) is a dependent name that is not looked-up immediately. • To tell the compiler that it is meant to refer to a type and not some other sort of member, you must add the keyword typename before it. template<typename T> struct first { typedef T * pointer; }; template<typename T> class second { first<T>::pointer p; // syntax error };
Indicating Base Classes • Base_func is inherited. • However, the standard says that unqualified names in a template are generally non-dependent and must be looked up when the template is defined. • Since the definition of a dependent base class is not known at that time (there may be specialisations of the base class template that have not yet been seen), unqualified names are never resolved to members of the dependent base class. template<typename T> class base { public: void base_func(); }; template<typename T> class derived : public base<T> { public: void derived_func() { base_func(); // error: base_func not defined } };
Vector • A sequence that supports random access to elements • Elements can be inserted and removed at the beginning, the end and the middle • Constant time random access • Commonly used operations • begin(), end(), size(), [], push_back(…), pop_back(), insert(…), empty()