470 likes | 489 Views
159.234 LECTURE. x. Review for Finals 2009. OOP. Final Exam. Q1. 20 marks Q2. 8 marks Q3. 12 marks Q4. 9 marks Q5. 12 marks Q6. 9 marks Total = 70 marks. 6 Questions. Different questions are worth different number of marks. 87% - C++ 13% - Java. Essentials.
E N D
159.234LECTURE x Review for Finals 2009 OOP
Final Exam Q1. 20 marks Q2. 8 marks Q3. 12 marks Q4. 9 marks Q5. 12 marks Q6. 9 marks Total = 70 marks 6 Questions Different questions are worth different number of marks. 87% - C++ 13% - Java
Essentials Dynamic memory handling, pass by address, pass by reference. String Stream processing, file handling Application: Class design and analysis Constructors, Destructors, data members, member functions Function Overloading, Operator Overloading Access modifiers, static variables, virtual functions & destructors Inheritance, Polymorphism, Function Templates, class Templates STL: vector, list, map; Algorithms: find, sort, erase, insert Java: Features removed from C++ Java: inheritance, interfaces, parameter passing, garbage collection
Dynamic Memory Handling 1 Memory Allocation, Deallocation in C++ Memory leak. new and delete operators • This is important because mishandling pointers could easily cause your program to crash.
159.234 POINTERS A pointer may be on the stack – but what it points to may be on the heap. Failing to free heap memory before exiting a function will leave memory on the heap that no longer has a pointer pointing to it. This memory can never be recovered – it is called a memory leak. Get into the habit of always freeing memory. Even when the program exits. Memory • Only C++ Memory will be covered in the exam.
159.234 New 1-D Array allocation via function call int new1D(char *&p, int elements){ p = new char[elements]; if(p == NULL) return 0; else return 1; } int alloc1D(char **p, int elements){ (*p) = (char*) malloc(elements * sizeof(char)); if((*p) == NULL) return 0; else return 1; } C-Memory vs. C++ Memory char *p; if(alloc1D(&p, 5)) { strcpy(p, "hello"); cout << "at main(): p = " << p << endl; } free(p); char *p; if(new1D(p, 5)) { strcpy(p, "hello"); cout << "at main(): p = " << p << endl; } delete [] p;
159.234 New 2-D Array allocation via function call int alloc2D(char ***p, int rows, int cols){ (*p) = (char **) malloc(rows * cols * sizeof(char *)); if((*p) == NULL) return 0; else return 1; for(int i=0; i < rows; i++){ //(*p)[i] = (char *) malloc(cols * sizeof(char)); //OK *((*p)+i) = (char *) malloc(cols * sizeof(char)); //OK //(*p)+i) = (char *) malloc(cols * sizeof(char)); //ERROR! if( *((*p)+i) == NULL) return 0; else return 1; } } int new2D(char **&p, int rows, int cols){ p = new char*[rows]; //array of pointers to char if(p == NULL) return 0; else return 1; for(inti=0; i < rows; i++){ p[i] = new char[cols]; //array of characters if( p[i] == NULL) return 0; else return 1; } } C-Memory vs. C++ Memory
159.234 New 2-D Array allocation via function call char **s; if(alloc2D(&s,rows,cols)){ s[0] = "FILE"; s[1] = "EDIT"; s[2] = "QUIT"; for(int i=0; i < rows; i++){ cout << "s[" << i << "]= " << s[i] << endl; } } //------------------------------ for(int i=0; i < rows; i++){ free(s[i]); } free(s); char **s; if(new2D(s,rows,cols)){ strcpy(s[0] , "FILE"); strcpy(s[1] , "EDIT"); strcpy(s[2] , “QUIT"); for(inti=0; i < rows; i++){ cout << "s[" << i << "]= " << s[i] << endl; } } //------------------------------ // free-up memory for(inti=0; i < rows; i++){ delete [] s[i]; } delete [] s; C-Memory vs. C++ Memory
Output String Stream #include <sstream> ostringstreamoss; int n = 44; float x = 3.14; oss<< "Hello!\t" << n << '\t' << x; string s = oss.str(); cout << endl << s << endl; Serves as a conduit to an anonymous string which can be read with the built-in oss.str() function that is bound to the ossobject Remember sprintf()?, how does it compare to this one? output_string_stream.cpp
Input String Stream const string buffer = oss.str(); istringstreamiss(buffer); string word; int m; float y; iss>> word >> m >> y; s = iss.str(); cout << endl << s << endl; cout << "word = " << word << endl; cout << "m = " << m << endl; cout << "y = " << y << endl; iss is defined and bound to buffer Contents of buffercan be accessed as elements of a string, or by formatted input through the iss object. Remember sscanf()?, how does it compare to this one? input_string_stream.cpp All extractions from isswill come from the contents of buffer, as if it were an external file.
#include <iostream> #include <fstream> #include <iomanip> #include <string> #include <sstream> using namespace std; int main(){ string s1("mydata.txt"); ifstreamin( s1.c_str() ); char buffer[1024]; while( in.getline( buffer, 1024 ) ){ string stemp( buffer ); cout << "Line is:" << stemp << endl; if( stemp[0] != '#' ){ stringstreamstris( stemp ); double d1, d2; stris >> d1 >> d2; cout << d1 << "," << d2 << endl; } cout << endl; } in.close(); return 0; } Using string example Input file: 1.0 2.0 1.1 2.4 1.8 2.8 #1.34 2.99 1.4 8.99 Example Output: Line is:1.0 2.0 1,2 Line is:1.1 2.4 1.1,2.4 Line is:1.8 2.8 1.8,2.8 Line is:#1.34 2.99 Line is:1.4 8.99 1.4,8.99 open a file Read one line of text, if there’s any available close file
int main(){ string s1("mydata.txt"); ifstream in( s1.c_str() ); string buffer; while(getline( in, buffer ) ) { cout << "Line is:" << buffer << endl; if( buffer[0] != '#' ){ istringstreamstris( buffer ); double d1, d2; stris >> d1 >> d2; cout << "data: " << d1 << "," << d2 << endl; } cout << endl; } in.close(); return 0; } #include <iostream> #include <fstream> #include <iomanip> #include <string> #include <sstream> using namespace std; int main(){ string s1("mydata.txt"); ifstream in( s1.c_str() ); char buffer[1024]; while( in.getline( buffer, 1024 ) ){ string stemp( buffer ); cout << "Line is:" << stemp << endl; if( stemp[0] != '#' ){ stringstreamstris( stemp ); double d1, d2; stris >> d1 >> d2; cout << d1 << "," << d2 << endl; } cout << endl; } in.close(); return 0; } Alternatively: (no C-style char*) File_stringstream2.cpp
Application 3 Tank Game Designed to allow the students to apply everything they’ve learned about OOP. This also helps the students to realise how important and effective OOP is in simplifying the development of the game. Try to imagine re-writing the codes you have submitted into its corresponding non-OOP form. How much more difficult the codes would turn out?
Application 3 World-to-Device coordinates representation Tank Game You should be able to describe the concept at least and come up with a class implementation (no need to memorize formulas). Using STL to implement the bombs with shrapnels How to implement a vector of bombs? Seespikes*.cpp The sophistication of Physics were abstracted, encapsulated and injected using classes. Interaction between classes: Tank, bomb, etc. Inheritance, polymorphism, friend classes & functions SeeLecture 16-Developing the Tank Game
159.234 WORLD-to-DEVICE COORDINATES 100,000,000 miles x 500,000 miles Transformation Equations 1280 x 1024 pixels +y 0 +x (Xworld,Yworld) (XDevice,YDevice) +x +y 0 World System of Coordinates Device System of Coordinates
159.234 TRANSFORMATION EQUATIONS World-to-Device Coordinates • You don’t need to memorize the equations to prepare for the exam.
159.234 Data Structures, data members World-to-Device Coordinates Inputs: x, y (World coordinates) - double BoundaryTypeWorldBound; BoundaryTypeDevBound; double xSlope, xInt; double ySlope, yInt; Does not change too often, only during initialisation and after zooming-in / zooming-out. outputs: x, y (device coordinates) -int
159.234 Data Structures, data members const double g = 9.8; World-to-Device Coordinates typedef struct { double x1,y1,x2,y2; } BoundaryType; class Transform{ ... private: BoundaryType WorldBound; BoundaryType DevBound; double xSlope, xInt; double ySlope, yInt; };
159.234 PHYSICS EQUATIONS Modifying timewill allow you to calculate the next x & y coordinates of the object. Projectile Motion where g= 9.8 m/sec.2pull of gravity Voinm/sec.initial velocity tinsec.time
159.234 PUTTING THE PIECES TOGETHER (non-OOP) // initGraphics here // initBoundaries here t=0.0; while(t < tf) { cleardevice(); setcolor(RED); circle (xDev(x(t, Vo, Theta)),yDev(y(t, Vo, Theta)), 12); t=t+tinc; } (Non-OOP) Projectile Motion xDev() - World-to-Device Transformation Function //circle(x, y, radius) x()- implements a Physics Equation for x-coordinate calculation
Slope and intercept values need to be calculated before the transformation from world to device could be performed. classTransform{ public: //constructor Transform(BoundaryTypeWBound, BoundaryTypeDBound) :WorldBound(WBound), DevBound(DBound) { //calculate slope and intercept if((WorldBound.x2-WorldBound.x1) == 0) xSlope = (DevBound.x2-DevBound.x1)/(WorldBound.x2- WorldBound.x1+.001); else xSlope = (DevBound.x2-DevBound.x1)/(WorldBound.x2-WorldBound.x1); xInt = DevBound.x1-xSlope*WorldBound.x1; //....and so on... } intxDev(double xWorld) const{return (int)ceil(xSlope*xWorld+xInt); } //from world to device ... private: BoundaryTypeWorldBound, DevBound; //...and so on... }; device
Only one instance is necessary for all animated objects in the game! //Instantiation Transformtfm(WBound, DBound); //passing the object as an argument to the drawing methods tank.draw(tfm); //draw function formal parameter definition void Tank::draw(const Transform & t) { //...implementationhere fillellipse(t.xDev( headX), t.yDev( headY) …); } Passed as a reference to a constant
Final Exam Templates Operator overloading You should know the details of implementation (e.g. assignment operator, subscripting operator, etc.) Constructors, Destructors arguments Formal parameters, actual parameters Using assert()
Final Exam Connecting Classes via Composition Data members and Member Functions You should know what happens to them when you connect classes via Composition. Constructors, Destructors
Final Exam Connecting Classes via Inheritance Data members and Member Functions You should know what happens to them when you connect classes via Inheritance. Constructors, Destructors Multiple Inheritance SeeLectures 15 & 16
Final Exam STL Containers: vector, list, map Algorithms: find, sort, insert, erase Iterators SeeLectures 20, 21 & 22
Final Exam Program structure, JVM SeeJava 1,2,3 Java Main function, creation & deletion of objects from the heap, how Java supports cross-platform application development? Paramater passing SeeJava 2 how to pass objects? Inheritance in Java SeeJava 3 Requirements when a class extends another class, What happens if you put a class inside another class? Interface in Java SeeJava 3 What happens when a class implements an interface?
159.234 Static Members of Classes class P { public: static char c; }; char P::c = 'W'; int main() { P x,y; cout << x.c; x.c = 'A'; cout << y.c; } Static members of classes: If a member variable is declared static, there is only one instance of that in the program. A static variable is common to all class variables. C++
When is a copy constructor called? SUMMARY • 1. When a copy of an object is required, such as in call-by-value. • Str p; • display(p); • 2. When returningan object by value from a function. • Point findMiddlePt ( Point p1,Point p2){ • Point temp ; • //---do something • return temp; • } • 3. When initializingan object to be a copy of another object of the same class. • Str x; • //...other statements here • Str y(x);//y declared and initialized with x • or • Str y = x;//y declared and initialized with x
Friend Functions/Classes Friend functions A 'friend' function has access to all 'private' members of the class for which it is a 'friend'. To declare a 'friend' function, include its prototypewithin the class, preceding it with the C++ keyword 'friend'.
Friend Functions/Classes Global functiona()can access private data in class T m() can access private data in classS all functions of classTcan access private data inclass X friendsshould be used with caution: they by-pass C++’s data hiding principle. It is the responsibility of the code for which access is to be given to say who it’s friends are - i.e. who does it trust! classT { public: friend void a(); intm(); private: // ... }; void a() {// can access // private data in T...} classS { public: friend intT::m(); //... }; class X { public: friend class T; //... };
Defining Operator Overloading To define an additional task to an operator, we must specify what it means in relation to the class to which the operator will be applied. This is done with the help of a special function called operatorfunction which describes the task. General form of an operator function: return type classname :: operator (op-arglist) { function body //task defined } Operator being overloaded operator is the function name
Polymorphism class two_d { public: two_d(double a, double b) : x(a), y(b) {} virtual double area(void) {return 0;} protected: double x,y; }; area is a called a virtualfunction.
Polymorphism class rect: public two_d{ public: rect(double a, double b, double ht, double wd) : two_d(a,b), h(ht), w(wd) {} virtual double area(void) {return w * h;} private: double h,w; }; area is a called a virtualfunction.
Polymorphism area() is a called a virtualfunction. The run-time system knows the types of objects that pointers point to! The appropriate function is called when we ask for p[i]->area() Here’s the code segment again: circle c,d; rect e,f; two_d* p[4]; p[0]=&c; p[1]=&d; p[2]=&e; p[3]=&f; for (inti=0;i<4;i++) { total += p[i]->area(); }
Pure Virtual Function class two_d { public: two_d(double a, double b) : x(a), y(b) {} virtual double area(void) = 0; protected: double x,y; };
Templates 19 Example: Vector Data members & some extra methods: protected: T* data; unsigned size; void copy(const Vector<T>&); Constructor: template <class T> Vector<T>::Vector(int n=100) : size(n) { assert(n>0); p = new T[size]; assert(p != NULL); }
Templates 19 operator[ ] template <class T> T& Vector<T>::operator[](int i) { assert((i>=0) && (i<size)); return p[i]; }
Templates 19 operator = template <class T> Vector<T>& operator=(const Vector<T>& v) { if(size > 0) { cout << "deleting previous contents..." << endl; delete [] data; } size = v.size; data = new T[size]; copy(v); return *this; }
Templates 19 Copy constructor //Copy constructor: X-X-ref Vector(const Vector<T>& v) : size(v.size) { cout << "\ncopy constructor called." << endl; data = new T[size]; copy(v); }
Templates 19 template<class T> void Vector<T> ::copy(const Vector<T>& v) { // intminSize = (size < v.size)? size : v.size; // for(inti=0; i < minSize; i++) { for(inti=0; i < size; i++) { data[i] = v.data[i]; } }
Templates 19 Using a Template Class Finally, this is how we use a template class: int main() { Vector<int> m(100); m[3] = 34; ... }
vector<int> v; #include <iostream> #include <vector> using namespace std; int main(){ vector<int> v; vector<int>::iterator it, start, end; for(int i=0;i<10;i++){ v.push_back(i); } cout << "v size = " << v.size() << endl; start = v.begin(); start += 3; // now points at element [3] end = start; end += 4; // now points at element [7] v.erase(start, end ); // erases 3,4,5,6 cout << "v size = " << v.size() << endl; for(it=v.begin();it<v.end();it++){ *it *= 10; } cout << "v contains: "; for(int i=0;i<v.size(); i++){ cout << " " << v[i]; } cout << endl; } Output: % a.out v size = 10 v size = 6 v contains: 0 10 20 70 80 90 A variable-sized vector the range includes all the elements between start and end, including the element pointed by start but not the one pointed by end.
map<string,int> m1, m2; map<string,int>::iterator iter; // points to a pair<string,int> string one("One"); string two("Two"); string three("Three"); string four("Four"); string five("Five"); m1[one] = 1; m2[two] = 2; m1[three] = 3; m2[four] = 4; m1[five] = 5; for(iter=m1.begin();iter!=m1.end();iter++){ cout << "Found " << iter->second << " keyed by " << iter->first << endl; } cout << endl; m1.swap(m2); for(iter=m1.begin();iter!=m1.end();iter++){ cout << "Found " << iter->second << " keyed by " << iter->first << endl; } Note: map’s iterator is a pointer to a pair - dereferenced using members first and second Output: % a.out Found 5 keyed by Five Found 1 keyed by One Found 3 keyed by Three Found 4 keyed by Four Found 2 keyed by Two map<key, val> An associative array (or dictionary, or table) • acts like an array whose index can be any type that implements the < operator. • e.g. key=StudentID, val = Student’s data Record
STL: vector struct Entry { string name; int number; friend int operator<(const Entry& e1, const Entry& e2); }; int operator<(const Entry& e1, const Entry& e2) { return (e1.name < e2.name); } vector<Entry> v; ... sort(v.begin(), v.end());
STL: map A map STL contains a built-in find function. map<string, int> phoneBook; //... it = phoneBook.find("ZNapoleon"); if(it != phoneBook.end()) { cout << "Entry found." << endl; cout << it->first << ", " << it->second << endl; } else { cout << "Entry is missing." << endl; }