Скачать презентацию Lecture 15 n C n Multiple Inheritance n Скачать презентацию Lecture 15 n C n Multiple Inheritance n

126cc93e33a0602289bae3a7b988925f.ppt

  • Количество слайдов: 50

Lecture 15 n C++ n Multiple Inheritance n Operator overloading n Templates n Pointers Lecture 15 n C++ n Multiple Inheritance n Operator overloading n Templates n Pointers n Dynamic memory allocation n Standard Template Library n Containers n Iterators n Algorithms

Lecture Schedule n n n Mon 5/11/01 (Bjoern) n Visual. Works/Smalltalk Mon 12/11/01 (Frank) Lecture Schedule n n n Mon 5/11/01 (Bjoern) n Visual. Works/Smalltalk Mon 12/11/01 (Frank) n C++ n Game playing (lab 4) n Course evaluation Tue 20/11/01 (Bjoern) n Visual. Works/Smalltalk

Inheritance super class subclass Feature A Feature B Feature C Feature D Inheritance super class subclass Feature A Feature B Feature C Feature D

Inheritance class Date { public: // visible outside class scope int Year(); … protected: Inheritance class Date { public: // visible outside class scope int Year(); … protected: // visible to sub-classes but hidden from rest of the world int day, month, year; }; class Date. Time : public Date { public: int Hours(); … private: // only visible to class Date. Time int hours, minutes };

Multiple Inheritance base class A subclass Feature A Feature B base class B Feature Multiple Inheritance base class A subclass Feature A Feature B base class B Feature C Feature D

Multiple Inheritance class Date { public: int Year(); private: int day, month, year; }; Multiple Inheritance class Date { public: int Year(); private: int day, month, year; }; class Time { public: int Hours(); private: int hours, minutes; };

Multiple Inheritance class Date. Time : public Date, public Time { public: Date. Time(int Multiple Inheritance class Date. Time : public Date, public Time { public: Date. Time(int d, int m, int y, int h, int mi); … }; Date. Time: : Date. Time(int d, int m, int y, int h, int mi) : Date(d, m, y), Time(h, mi) { }

Ambiguity in Multiple Inheritance class Date { void add(int days); }; class Time { Ambiguity in Multiple Inheritance class Date { void add(int days); }; class Time { void add(int minutes); }; Class Date. Time : public Date, public Time { }; Date. Time dt(13, 2, 1998, 23, 10); dt. add(3); // ambiguous -- will not compile dt. Date: : add(4); // uses add of class Date dt. Time: : add(5); // uses add of class Time

Ambiguity in Multiple Inheritance class A { public: void F(); }; class B : Ambiguity in Multiple Inheritance class A { public: void F(); }; class B : public A { …}; class C : public A { …}; class D : public B, public C {}; D d; d. F(); // ambiguous - won´t compile diamond shaped inheritance tree class A class B class C class D

Overloading Operator n n n Operator overloading is a useful feature of object oriented Overloading Operator n n n Operator overloading is a useful feature of object oriented programming Operator overloading allows it to give normal C++ operators such as +, -, ==, < additional meanings It makes statements more intuitive and readable for example: Date d 1(12, 3, 1989); Date d 2; d 2. add_days(d 1, 45); // can be written with the + operator as d 2=d 1+45;

Operator Overloading The name of an operator function is the keyword operator followed by Operator Overloading The name of an operator function is the keyword operator followed by the operator itself. class complex { double re, im; // re and im part of a complex number public: complex (double r, double i) : re(r), im(i) {}; //constructor complex operator+(complex c); // operator function }; complex c 1(2. 2, 3. 0); // instantiate complex c 1 complex c 2(1. 0, -4. 5); // instantiate complex c 2 complex c 3=c 1+c 2; // shorthand notation for c 1 + c 2 complex c 4=c 1. operator+(c 2); // explicit call n

Overloading Unary Operators class Date { Date& operator++(); // prefix increment operator } Date& Overloading Unary Operators class Date { Date& operator++(); // prefix increment operator } Date& Date: : operator++ () { if (++day > days_in_month()) { day=1; if (++month > 12) { month=1; year++; } } return *this; } Date d 1(31, 12, 1999); ++d 1; // results in 1. 1. 2000

Overloading Unary Operators class Date { Date operator++(int); // postfix increment operator }; Date: Overloading Unary Operators class Date { Date operator++(int); // postfix increment operator }; Date: : operator++ (int) { Date old(*this); if (++day > days_in_month()) { day=1; if (++month > 12) { month=1; year++; } } return old; } Date d 1(31, 12, 1999); Date d 2; d 2=d 1++; // assigns 31. 12. 01 to d 2, d 1 becomes 1. 1. 2000

Overloading Binary Operators class Date { Date operator+(int days) const; }; Date: : operator+(int Overloading Binary Operators class Date { Date operator+(int days) const; }; Date: : operator+(int days) const; { Date tmp=*this; // copy object for (int i=0; i < days; i++) ++tmp; return tmp; } Date d 1(1, 4, 1999); Date d 2=d 1+25; // results in 26. 4. 2000

Overloading Binary Operators class Date { Date& operator+=(int days); // must be reference as Overloading Binary Operators class Date { Date& operator+=(int days); // must be reference as += modifies // the left hand argument }; Date& Date: : operator+=(int days) // return type reference to object { for (int i=0; i < days; i++) *this++; return *this; // return reference to object } Date d 1(1, 4, 1999); d 1+=25; // results in 26. 4. 2000

Overloading Relational Operators class Date { bool operator==(Date d) { return (day==d. day) && Overloading Relational Operators class Date { bool operator==(Date d) { return (day==d. day) && (month=d. month) && (year==d. year); }; bool operator<(Date d) { if (year < d. year) return true; else if (year==d. year) && (month < d. month) return true; else return (month==d. month) && (day < d. day); }; };

Overloading Binary Operators int Date: : operator-(Date d) const { int days=0; if (*this Overloading Binary Operators int Date: : operator-(Date d) const { int days=0; if (*this > d) while (*this != ++d) days++; else while (*this != --d) days--; return days; } Date d 1(24, 4, 1988); Date d 2(13, 3, 1998); int diff = d 1 -d 2; // diff = 42

Templates n n n A template is a place-holder for an arbitrary built-in or Templates n n n A template is a place-holder for an arbitrary built-in or user-defined data type Templates make is possible to use one function or class to handle many different data types Function templates allow a parameter to assume an arbitrary data-type Class templates allow a member data to assume an arbitrary data-type Templates are another example for polymorphism

Function Templates int max(int a, int b) // one max function for int { Function Templates int max(int a, int b) // one max function for int { if (a>b) return a; else return b; } double max(double a, double b) // max function for double { if (a>b) return a; else return b; }

Function Templates template <class Type> // class Type placeholder for concrete data type Type Function Templates template // class Type placeholder for concrete data type Type max( Type a, Type b) // substitute template. Type for concrete type { if (a>b) return a; else return b; // identical code } void main() { int a=3, b=2; Date d 1(17, 5, 1998); // assume operator > is defined for class Date d 2(23, 6, 1997); int c=max(a, b); // template T replaced with int char z=max(’f’, ’q’); // template T replaced with char Date d 3=max(d 1, d 2); // template T replaced with date }

Function Templates argument type determines function instantiation int i 1, i 2, i 3; Function Templates argument type determines function instantiation int i 1, i 2, i 3; i 3=max(i 1, i 2); int max(int a, int b) { … }; template T max(T a, T b) { … }; char c 1, c 2, c 3; c 3=max(c 1, c 2); char max (char a, char b) { … }; one function template in source file Date d 1, d 2, d 3; d 3=max(d 1, d 2); Date max (Date a, Date b) { … };

Class Templates Array. h template <class Type> // template class Type class Array // Class Templates Array. h template // template class Type class Array // array of arbitrary data type { public: Array(unsigned int sz); Type& operator[](unsigned int i); // returns a reference to i-th element Type operator()(unsigned int i); // returns the value of i-th element private: static int max_size=100; unsigned int size; Type array[100]; // placeholder for concrete data type };

Class Templates Array. C #include ”Array. h” template class<Type> Array<Type>: : Array(unsigned int sz) Class Templates Array. C #include ”Array. h” template class Array: : Array(unsigned int sz) { if (sz > max_size) size=max_size; else size=sz; } template class Type& Array: : operator[](unsigned int i) { if (i Type Array: : operator()(unsigned int i) { if (i

Class Templates Array<double> x(20); // instantiates a double array of size 20 Array<Date> dates(10); Class Templates Array x(20); // instantiates a double array of size 20 Array dates(10); // instantiates a Date array of size 10 Date christmas(24, 12, 2001); x[10]=5. 7; // operator [] returns reference can be used on rhs dates[3]=christmas; x[11]=x(10)+3. 4; // operator () returns value can only be used on lhs x[0]=1. 2; for (int i=1; i<20; i++) x[i]=x(i-1)*1. 2; for (int i=0; i<10; i++) dates[i]++; // increment all dates by one calendar day

Class Templates n n G++ has two compiler options n -fexternal-templates n -fno-external-templates The Class Templates n n G++ has two compiler options n -fexternal-templates n -fno-external-templates The later compiler directive is the default one and you need to arrange for all necessary instantiations to appear in the implementation file (. C) for example in Array. C #include Array. h template class Array: : Array(unsigned int sz) {. . . }. . . template class Array; // explictly instantiate Array template class Array; // explictly instantiate Array

Pointers n n n Pointers and Arrays Pointers and function arguments Dynamic memory management Pointers n n n Pointers and Arrays Pointers and function arguments Dynamic memory management New and delete

Pointers n n n Pointers are used to: n Access array elements n Passing Pointers n n n Pointers are used to: n Access array elements n Passing arguments to functions when the function needs to modify the original argument n Passing arrays and strings to functions n Obtaining memory from the system n Creating data structures such as linked lists Many operations that require pointers in C can be carried out without pointes in C++ using reference arguments instead of pointers, strings instead of char arrays or vectors instead of arrays Some operations still require pointers, for example creating data structures such as linked lists and binary trees

Pointers n n n Each variable in a program occupies a part of the Pointers n n n Each variable in a program occupies a part of the computer’s memory, for example an integer variable occupies 4 bytes of memory The location of the piece of memory used to store a variable is called the address of that variable An address is some kind of number similar to house numbers in a street that is used to locate the information stored in that particular variable int i; address of i char c; address of c short s; address of s 0 x 1054 0 x 1055 0 x 1056 0 x 1057 0 x 1058 0 x 1059 0 x 1060 10101011 00001111 1000 1110001110111100

Pointer Variables n n A pointer variable is a variable that holds address values Pointer Variables n n A pointer variable is a variable that holds address values Each data type has its own pointer variable, pointer to int, pointer to double, pointer to char, … C/C++ uses the address-of operator & to get the address of an variable C/C++ uses the indirection or contents-of operator * to access the value of the variable pointed by int i=17; int* ptr; // defines a pointer to an integer variable ptr= &i; // assign the address of x to pointer cout << *ptr << endl; // prints contents of variable i

Pointer Variables 0 x 1054 int i; int *ptr; ptr=&i; dd a res of Pointer Variables 0 x 1054 int i; int *ptr; ptr=&i; dd a res of s t en nt co cout << *ptr << endl; of s 17

Pointer Variables int v; // defines variable v of type int w; // defines Pointer Variables int v; // defines variable v of type int w; // defines variable w of type int *p; // defines variable p of type pointer to int p=&v; // assigns address of v to pointer p v=3; // assigns value 3 to v *p=7; // assigns value 7 to v p=&w; // assigns address of w to pointer p *p=12; // assigns value 12 to w n Using the indirection operator *p to access the contents of a variable is called indirect addressing or dereferencing the pointer

Pointers and Arrays n n n There is a close association between pointers and Pointers and Arrays n n n There is a close association between pointers and arrays Arrays can be accessed using pointers The name of an array is also a constant pointer to the data type of the elements stored in the array int array[5] = { 23, 5, 12, 34, 17 }; // array of 5 ints for (int i=0; i< 5; i++) cout << array[i] << endl; // using index to access elements for (int i=0; i< 5; i++) cout << *(array+i) << endl; // using pointer to access elements // array is of type pointer to integer

Pointers as Function Arguments n n n C/C++ offers three different ways to pass Pointers as Function Arguments n n n C/C++ offers three different ways to pass arguments to a function n by value : void f(int x); n by reference : void f(int& x); n by pointer : void f(int* x); In passing by value the function obtains only a local copy of the variable, so that changes to the local variable have no impact on the argument with which the function was invoked In passing by reference and passing by pointer the function manipulates the original variable rather than only a copy of it

Pointers as Function Arguments void swap( double& x, double& y) { double tmp=x; x=y; Pointers as Function Arguments void swap( double& x, double& y) { double tmp=x; x=y; // access variable by its alias name y=tmp; } void swap( double* ptr 1, double* ptr 2) { double tmp=*ptr 1; *ptr 1=*ptr 2; // de-referencing pointer *ptr 2=tmp; } double a=3. 0; double b=5. 0 swap(a, b); // call by reference to variables a and swap(&a, &b); // call by pointer using the addresses of a and b

Bubble. Sort void bsort (double *ptr, int n) // pass pointer to array and Bubble. Sort void bsort (double *ptr, int n) // pass pointer to array and // size of array as arguments to bsort { int j, k; // indices to array for (j=0; j *(ptr+k)) swap(ptr+j, ptr+k); } double array[6] = { 2. 3, 4. 5, 1. 2, 6. 8, 0. 8, 4. 9 }; bsort(array, n); // sort the array

Const Modifiers and Pointers n The use of the const modifier with pointers is Const Modifiers and Pointers n The use of the const modifier with pointers is confusing as it can mean two things n const int* cptr. Int; // cptr. Int is a pointer to a const int You can not the change the value of the integer that cptr. Int points to but you can change the pointer itself n int* const ptrc. Int; // ptrc. Int is a constant pointer to int You can change the value of the integer that ptrc. Int points to but you can not change the pointer itself

Memory Management In order to create an array in C/C++ you have to know Memory Management In order to create an array in C/C++ you have to know its size in advance during compile time, in other words it has to be a constant int size; cout << ”Enter size of array : ”; cin >> size; int array[size]; // ERROR size has to be a constant n Solution in C++, use vector class from the STL which is expandable n

Memory Management Date* Create. Date() // allows the user to create a date object Memory Management Date* Create. Date() // allows the user to create a date object { int day, month, year; char dummy; cout << ”Enter dd/mm/yyyy : ”; cin >> day >> dummy >> month >> dummy >> year; Date date(day, month, year); return &date; // ERROR!! Scope of date ends with end of function } Date *ptr; ptr=Create. Date(); // call Create. Date() to generate a new date cout << ”You entered ” << *ptr << endl; // variable to which ptr points no longer exist , segmentation fault !!!

Memory Management n n The new operator in C++ can be used to create Memory Management n n The new operator in C++ can be used to create objects on the heap that are ”alive” after returning from a function Objects allocated in dynamic memory are called heap objects or to be ”on free store” and have a permament existence Date* Create. Date() // allows the user to create a date object { int day, month, year; char dummy; cout << ”Enter dd/mm/yyyy : ”; cin >> day >> dummy >> month >> dummy >> year; Date *tmpptr = new Date(day, month, year); return tmpptr; // returns pointer to heap object } Date *ptr; ptr=Create. Date(); // call Create. Date() to generate a new date cout << ”You entered ” << *ptr << endl; // ok, ptr refers to heap object

Memory Management New can also be used to allocate blocks of memory n The Memory Management New can also be used to allocate blocks of memory n The delete operator is used to release the memory allocated with new once it is no longer needed #include char *str =”This is an old C-style string”; int len=strlen(str); // computes the length of str char *ptr; // create a pointer to char ptr = new char[len+1]; // set aside memory string + ’’ strcpy(ptr, str); // copy str to new memory cout << ”ptr=” << ptr << endl; delete [] ptr; // release ptr’s memory n

New Operator in Constructors class String // user-defined string class { private: char* str; New Operator in Constructors class String // user-defined string class { private: char* str; // pointer to block of characters public: String(char* s) // one-argument constructor { int length=strlen(s); // length of string argument str = new char[length+1]; // allocate memory strcpy(str, s); // copy argument to it } ~String() // destructor { delete [] str; } void Display() { cout << str << endl; } }; String mystring=”This is my string of Type String”; mystring. Display();

Pointers to Objects n Pointers can point to objects as well as to built-in Pointers to Objects n Pointers can point to objects as well as to built-in data types Date date; // define a named Date object date. Set(12, 3, 1996); // set the date. Display(); // display the date Date *dateptr; // define a pointer to a Date object dateptr=new Date; // points to new Date object dateptr->Set(9, 12, 1999); // set date using -> operator dateptr->Display(); // display date (*dateptr). Display(); // works as well but less elegant

Linked List Example n n A linked list is composed of a chain of Linked List Example n n A linked list is composed of a chain of elements (links). Each element contains some data and a pointer to the next element in the list. In a double linked list, each element also contains a pointer to its predecessor. Element next data Element next prev data

Linked List Example struct link // one element of list { int data; // Linked List Example struct link // one element of list { int data; // data item link *next; // pointer to next element }; class linklist { private: link* first; // pointer to first link public: linklist() { first = NULL; } // no argument constructor void push_back(int d); // add new element to the end of list int pop_back(); // delete last element and return data value void push_front(int d); // add new element to the front of list int pop(); // delete first element and return data value void display(); // display all elements in list }

Linked List Example void linklist: : push(int d) // add data item at the Linked List Example void linklist: : push(int d) // add data item at the front { link* newlink = new link; // create a new link newlink->data = d; // assign new data d newlink->next=first; // it points to the next link first = newlink; // now first points to this link }

Linked List Example int linklist: : pop() // remove element at the front { Linked List Example int linklist: : pop() // remove element at the front { int tmp_data = first->data; link* tmp=first; first=first->next; delete tmp; // free storage return tmp_data; } int linklist: : pop_back() // remove element at the end { link* tmp=first; while (tmp->next != NULL) tmp=tmp->next; int tmp_data = tmp->data; delete tmp; // free storage return tmp_data; }

Linked List Example void linklist: : push_back(int d) // add data item at the Linked List Example void linklist: : push_back(int d) // add data item at the end { link* newlink = new link; // create a new link newlink->data = d; // assign new data d newlink->next = 0; // points to nil link* tmp=first; if (tmp == NULL) // empty list first=newlink; else { while (tmp->next!=NULL) tmp=tmp->next; tmp->next=newlink; // it points to the next link } }

Linked List Example void linklist: : display() // display all links { link* tmp=first; Linked List Example void linklist: : display() // display all links { link* tmp=first; // set ptr to first link while(tmp != NULL) // until ptr points beyond last link { cout << current->data << ” ”; // print data current=current->next; // move to next link } }

Linked List Example template <class T> struct link // one element of list { Linked List Example template struct link // one element of list { T data; // data item link *next; // pointer to next element }; template class linklist { private: link* first; // pointer to first link public: linklist() { first = NULL; } // no argument constructor void push(T t); // add data item (one link) T pop(); void display(); // display all links }

Linked List Example template <class T> void linklist<T>: : push(T t) // add element Linked List Example template void linklist: : push(T t) // add element at the front { link* newlink = new link; // create a new link newlink->data = t; // give it data d newlink->next=first; // it points to the next link first = newlink; // now first points to this link } template void linklist: : display() // display all links { link* current=first; // set ptr to first link while(current != NULL) // until ptr points beyond last link { cout << current->data << ” ”; // print data current=current->next; // move to next link } }