Download presentation
Presentation is loading. Please wait.
Published byMaurice Atkinson Modified over 6 years ago
1
Characteristics of OOPL Templates Standard Template Library
Review Characteristics of OOPL Templates Standard Template Library
2
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
3
Encapsulation
4
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 Aim of class: a) provide the programmer with a tool for creating new types that can be used as conveniently as the built-in types (like float) b) user-defined type why? Separate the incidental details of the implementation from the properties essential to the correct use of it 2. Derived class, templates: organizing related classes that allow the programmer to take advantage of their relationships.
5
Class Define a Class Type
class Rectangle { private: int width; int length; public: void set(int w, int l); int area(); }; class class_name { permission_label: member; ... }; Header Body
6
Class Class 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 WHY? a) Sometimes, some constraints can cause a class to be useless outside the context. Users will be annoyed by using such context-dependent classes b) machine becomes messy. c) public permission is not willing to be given. Allocated in static memory, constructed once and persists to the end of the program, always has the same address. All objects belonging to the same class share these ( data or functions) We are going to talk one application of this next time when we talk about construction of an object.
7
Class Class 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 1. Functions declared within a class definition are member functions.
8
Class Define a Member Function
class Rectangle { private: int width, length; public: void set (int w, int l); int area() {return width*length; } } class name member function name scope operator inline 1.Different structures can have member functions with the same name. 2. If defined outside, the structure name when defining a member function must be specified. (::) 3.In a member function, member names can be used without explicit reference to an object (non member fuctions). In this case, the name refers to the member of the object for which the function was invoked. Always know for which object it was invoked. 4. Inline function: the compiler is requested to insert the complete body of the function in every place that the function is called, rather than generation code to call the function in the one place it is defined void Rectangle :: set (int w, int l) { width = w; length = l; } r1.set(5,8); rp->set(8,10);
9
Class Class Definition – Member Functions
static member function const member function declaration return_type func_name (para_list) const; definition return_type func_name (para_list) const { … } return_type class_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 A static member can be referred to without mentioning an object ( function call outside of the class, but need to be with the name of it’s class. Usage: let the compiler help you find errors, fast and lass expensive. 3. A const member function can be invoked for both const and non-const objects, but a non-const member function can be invoked only for non-const objects. F( const type& m)
10
Class Class 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 is public in structs Here is the difference between struct and class. Struct is one kind of class. Struct is a class whose members are public by default. (simple examples here) WHY? Generally, any change to the behavior of the class type can and must be effected by changes to its members. Usage: a) For example: Debugging. Illegal value must be caused by code in a member function. b) if we want to change the representation of a class, we need only change the member functions. User code directly depends only on the public interface and need not be rewritten. c) a potential user need examine only the definition of the member functions in order to learn to use a class because other functions cannot deal with the data.
11
Object Declaration 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; }
12
Object Declaration class Rectangle { private: int width; int length;
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 = 5 length = 8 width length
13
Object Declaration class Rectangle { private: int width; int length;
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 width length r1 width = 5 length = 8 5000 r2 width = 8 length = 10 6000 ??? 5000
14
Object Declaration class Rectangle { private: int width; int length;
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 ??? r3 6000 width length 5000 ??? NULL width = 80 length = 100
15
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 class circle c1.radius = 5; // Initialize by assignment } 1. aggregation
16
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 public member function cout << "The radius of circle c is " << c.get_r() << endl; // access a private data member with an accessor }
17
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 There is no return type Are used to initialize class data members Have the same name as the class They are publicly accessible They have different signatures a) When you initialize for class objects, some functions need writing to do the tasks. b) constructor in case the programmers forget it, the compiler will run it automatically when you create an object. 3)
18
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);
19
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(); width length width = 20 length = 50 5000 ??? r7 6000
20
Object Cleanup 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
21
Inheritance
22
Define a Class Hierarchy
Syntax: class DerivedClassName : access-level BaseClassName 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
23
Access Rights of Derived Classes
Type of Inheritance private protected public Access Control for Members The type of inheritance defines the minimum access level for the members of derived class that 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 In a public base class, public and protected members of the base class remain public and protected members of the derived class. In a protected base class, public and protected members of the base class are protected members of the derived class. In a private base class, public and protected members of the base class become private members of the derived class. In all cases, private members of the base class remain private. Private members of the base class cannot be used by the derived class unless friend declarations within the base class explicitly grant access to them.
24
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
25
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);
26
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;} } A derived class constructor can specify initializes for its own members and immediate bases only; it cannot directly initialize members of a base output: A:parameter C C test(1);
27
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); }
28
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;} } Base class: superclass, Derived class: subclass
29
Operator overloading Programmer can use some operator symbols to define special member functions of a class Provides convenient notations for object behaviors
30
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 translates into a function call if this function is defined within class obj1 if this function is defined outside the class obj1
31
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 = a.operator+ (b);
32
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; c = operator+ (a, b); Complex operator +(Complex &op1, Complex &op2) { double real = op1.real() + op2.real(), imag = op1.imag() + op2.imag(); return(Complex(real, imag)); }
33
Implementing Operator Overloading
Defined as a friend function class Complex { ... public: friend Complex operator +( const Complex &, const Complex & ); }; c = a+b; c = operator+ (a, b); Complex operator +(Complex &op1, Complex &op2) { double real = op1._real + op2._real, imag = op1._imag + op2._imag; return(Complex(real, imag)); }
34
Polymorphism
35
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 4. pass-by-pointers a) int add(int x, int y) {} Int multiply(int x, int y) (I) int main() { int nX; cout << "Enter a number: "; cin >> nX; Int result; If(nx%2 == 0) result = add(nx, nx); } Else Result = multiply(nx, nx); (II) Int (*func)(int, int); //created a function pointer Func = add; Func = multiply; Int result = func(nx, nx); 5. Less efficient, cause indirect call, but it’s more flexible
36
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
37
Virtual Functions Virtual Functions overcome the problem of run time object determination Keyword virtual instructs the 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 it knows which function to call based on the actual type of the object
38
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 Function virtual 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
39
Templates
40
typename variableIdentifier
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
41
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)
42
typename variableIdentifier
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
43
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.
44
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;
45
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++; } Function overloading
46
Another Template Example: passing two parameters
template <class T, int size> class Stack {... T buf[size]; }; Stack<int,128> mystack; non-type parameter
47
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; }; class second { first<T>::pointer p; // syntax error Dependent names are names whose definitions are considered to depend upon the template parameters and for which there is no declaration within the template definition. They are resolved only when the template is instantiated.
48
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(); }; class derived : public base<T> { public: void derived_func() { base_func(); // error: base_func not defined } Where names in the template are supposed to refer to base class members or to indirect base classes, they can either be made dependent by qualifying them or brought into the template's scope with a using-declaration. In the example, this could be achieved by replacing the call to base_func() with this->base_func() or base<T>::base_func(), or by adding the declaration using base<T>::base_func;.
49
STL
50
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()
51
Example of vectors // Instantiate a vector vector<int> V;
// Insert elements V.push_back(2); // v[0] == 2 V.insert(V.begin(), 3); // V[0] == 3, V[1] == 2 // Random access V[0] = 5; // V[0] == 5 // Test the size int size = V.size(); // size == 2
52
Stacks, Queues, and Deques
Stacks, queues, and deques (for double-ended queues) are simple containers that allows O(1) insertion and deletion at the beginning and/or end. You cannot modify any elements inside the container, or insert/remove elements other than at the ends. However, because they are templatized, they can hold just about any data types, and are tremendously useful for many purposes. A queue is a First-In-First-Out (FIFO) container, whereas a stack is Last-In-First-Out (LIFO). A deque is both a stack and a queue. A stack has pretty much all the methods of a queue, including push(), pop(), size(), empty(). However, instead of front(), a stack accesses the top of the stack with top(). And of course, pop() will retrieve the element at the top (or end) of the stack, not the front. Finally, a deque has both the features of a stack and a queue. It has the member methods size() and empty(), but instead of the push(), pop() combination, it now provides 4 different methods, all pretty much self-explanatory: push_front(), push_back(), pop_front(), pop_back().
53
STL - Stacks, Queues, and Deques
#include <stack> #include <queue> // either one will provide deque queue< int > Q; // Construct an empty queue for( int i = 0; i < 3; i++ ) { Q.push( i ); // Pushes i to the end of the queue // Q is now { “0”, “1”, “2” } } int sz = Q.size(); // Size of queue is 3 while( !Q.empty() ) { // Print until Q is empty int element = Q.front(); // Retrieve the front of the queue Q.pop(); // REMEMBER to remove the element! cout << element << endl; // Prints queue line by line
54
Lists #include <list> Doubly-linked list
Allowing insertion, deletion and modification of elements at the front, the back and in the middle size, push_back, push_front, pop_back and pop_front. Mechanism of iterators is needed
55
Iterators Vectors, lists, queues, etc. are all examples of collections. In fact, they are all subclasses of a Container class in STL An iterator is like a reference (or pointer) to one of the elements of a collection. Supports at least two operations: 1) ++ operator: advance forward one position 2) unary * operator : return the element being referenced
56
Lists & Iterators: Example
list< int > c; //Creates an empty list of integers c.push_back( 3 ); c.push_back( 5 ); c.push_front( 6 ); //Add 3 elements to the list, 6, 5, 3 for( list< int >::iterator i = c.begin(); i != c.end(); ++i ) { cout << " " << *i; } So we have initialized an iterator, i, to reference the first integer in the list. In this case, *i has type int. In general, for a list of type "list< C >", *i would have type C. 3. The begin() method of every collection returns an iterator pointing to the first element of the collection. 4. The end() method returns an iterator pointing to the position in the collection that is one after the last element. In other words, when i is equal to c.end(), i has run off the end of the list and is pointing to a nonexistent position – the loop should then stop. 5. *i – the value that i is referencing. Result: _6_3_5
57
Sets #include <set>
It is a sorted collection of elements, stored as a balanced binary search tree. No push_back or push_front , insert() instead.(sorted) To store elements of type C in a set, the < operator must be defined for type C. (Opertator Overloading) ( You can safely declare sets of int, double, char or any othe primitive types because you can use the < operator to compare two ints, two doubles or two chars – the operator is already defined in C++. ) 1. Insertion time: O(log(n))
58
Sets: Example set< string > ss; //creates an empty set of strings, #include <string> ss.insert( "Sheridan" ); ss.insert( "Delenn" ); ss.insert( "Lennier" ); //add elements to the set for( set< string >::iterator j = ss.begin(); j != ss.end(); ++j ) { cout << " " << *j; } 1. set< string >::iterator : class name for an iterator over a set of strings 2. j: iterator, initialized to ss.begin() 3. ss.begin(): smallest element; ss.end(): one after the last element of the set 4. ++j increments the iterator. *j returns the string being referenced by j. Result: _Delenn_Lennier_Sheridan
59
Maps #include <map>
store key-value pairs rather than collection of elements. maps are sorted by the keys. Implemented using balanced binary search trees. insertion, deletion and update operations require logarithmic time in the size of the map. The map class has 2 template parameters – key type and value type. (using [] to access entries) 1. The simplest way to visualize a map is to think of a dictionary that for each word (key) gives a description (value).
60
Maps: Example vector< string > i2s( 7 );
i2s[0] = "Sunday"; i2s[1] = "Monday"; i2s[2] = "Tuesday"; i2s[3] = "Wednesday“; i2s[4] = "Thursday"; i2s[5] = "Friday"; i2s[6] = "Saturday"; map< string, int > s2i; for( int i = 0; i < 7; i++ ) { s2i[i2s[i]] = i; } i2s[i] is the name of the day, and we are mapping it to the corresponding integer using the map s2i. As a result, s2i["Sunday"] will be 0, s2["Monday"] will be 1, etc.
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.