Factorial Preparatory Exercise #include using namespace std; double fact(double); int fact(int); int main(void) { const int n=20; ofstream my_file("results.txt"); for (int i=0; i<=n; i++) { cout << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; my_file << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; } return 0; } int fact(int x) { int i=1; for (int j=1; j<=x; j++) { i=i*j; } return i; } double fact(double x) { double fact=1; for (int j=1; j<=x; j++) { fact=fact*j; } return fact; } x int x! double x! e e e e e e e e e e e+18
Dissecting the C++ program #include using namespace std; double fact(double); int fact(int); int main(void) {... return 0; } Include “standard C++ libraries” iostream - screen output / keyboard input fstream - file input / output iomanip - manipulate output [e.g. setw(n)] “function prototypes” so we can use a function before it is defined only needs types not variable names namespace --> a collection of objects cout, cin, endl, fstream, … std using namespace std; merges things in “std” into global/main namespace …thus avoid doing std::cout etc. x, y, z, j nsp1 x, y, w, k nsp2... cout << nsp1::x cout << nsp2::x Two namespaces --> x’s are different things
Example: fact(6) i j int fact(int x) { int i=1; for (int j=1; j<=x; j++) { i=i*j; } return i; } The integer factorial function Dissecting … const int n=20; ofstream my_file("results.txt"); for (int i=0; i<=n; i++) { cout << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; my_file << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; } ofstream --> is a class my_file --> is an object of “class ofstream” Inside the main() function - 1 Before loop End of 1st iterartion
Variable “x” inside function is LOCAL copy although x = 200 now the “i” in fact(i) is not affected This variable “ i ” LOCAL. i.e. the “ i ” in main() is hidden & unaffected int fact(int x) { int i=1; for (int j=1; j<=x; j++) { i=i*j; } x = 200 ; return i; } The integer factorial function Dissecting … function & argument const int n=20; ofstream my_file("results.txt"); for (int i=0; i<=n; i++) { cout << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; my_file << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; } Inside the main() function
Passing a reference The integer factorial function const int n=20; ofstream my_file("results.txt"); for (int i=0; i<=n; i++) { cout << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; my_file << i << '\t' << setw(14) << fact(i) << setw(14) << fact(1.0*i) << endl; } Inside the main() function The “&” makes a difference Variable “x” inside function is now a local name for the “i” in fact(i) So now i = 200 after fact(i) returns and the “for loop” in main() will finish early Allows you to update a variable in main() from another function: e.g. variables of type “ofstream” int fact(int& x) { int i=1; for (int j=1; j<=x; j++) { i=i*j; } x = 200 ; return i; }
OOP: Classes & Objects AIM: to extend C++ by –Defining new types of variables –New variables may be composed of several existing variables –Also define actions that can be done on/with the variables class description of “new variable type” ; contains… – Data members the variables it is composed of: defines state – Methods special functions that act on objects of the class object a particular variable of the class objects classes threevector v1 ; complex z, w ;
double x double y double z threevector Schematic of a Class Object 1 Object 2 class methods constructors() accessors() modifiers() other() data members Object 3 print() + – * threevector() constructors() square() accessors() setx() modifiers()
Creating / Initializing an object General syntax class_type object ; class_type object(initialization data) ; Examples using “threevector” objects threevector v1 ; v1 xyz 0.0 threevector u(1.0,2.3,-0.2) ; u xyz –0.2 (invokes default constructor that in this case sets all components to zero) (invokes Cartesian constructor)
set_im() Classes - another example complex number complex(a,b) pow(n) + complex() real() conj() double re double im * data members methods
Using an object General syntax Examples using “complex number” objects object.method() ; result = object.method(arguments) ; complex z ; z reim 0.0 complex w(3.0,4.0) ; z = w.conj() ; w reim – 4.0
Using an object (2) result = object.method(arguments) ; z.set_im(0.0) ; Modifier method z reim 3.0 – Access method cout << “|w| = “ << w.modulus() << endl ; |w| = 5.0 (screen output) Complex # arithmetic p reim complex p = z + w ; complex q = p / w ; q reim 1.36 – 0.48
Class Definition — C++ Syntax class complex { private: // Data members // Hidden methods public: // Constructors // Accessible methods }; File “complex.h” Name of the class
Class Definition — C++ Syntax File “complex.h” class complex { private: double re, im ; public: // Constructors & methods }; Data members class complex { private: double re, im ; public: complex(){...} double modulus(){...} complex operator+(complex z) {...} }; Methods
complex w(3.0,4.0) ; w reim complex z ; z reim 0.0 default constructor Constructors complex() { re = 0.0 ; im = 0.0 ; } In “complex.h” complex(double a, double b) { re = a ; im = b ; } ; They are methods with the same name as class What do they do? Take care of initializing new objects Return the object they create (no return type explicitly needed) Example usage;
Constructors — Overloading In “complex.h” // “Regular” Constructor complex(double a, double b) {... } // Polar Constructor complex(double r, double phi) { re = r * cos(phi) ; im = r * sin(phi) ; } Overloading… Multiple methods with… — distinguishable pattern of arguments — same name “Regular” Constructor double Polar double complex z2(1.0, 0.5) ; Error - Ambiguous
Constructors — Overloading In “complex.h” // “Regular” Constructor complex(double a, double b) {... } // Polar Constructor complex(double r, double phi, int dummy) { re = r * cos(phi) ; im = r * sin(phi) ; } ; Overloading… Multiple methods with… — distinguishable pattern of arguments — same name “Regular” Constructor Polar double int complex z2(1.0, 0.5) ; Okay - regular complex z3(1.0, 0.5, 0) ; Okay - polar
data member of object invoking method nothing returned return type Access & Modifier Methods // Access method double modulus() { return sqrt(re*re + im*im) ; } In “complex.h” // Modifier method void set_im(double i_new) { im = i_new ; } complex w(3.0,4.0) ; double r = w.modulus() ; Example usage; complex z ; w.set_im(-1.0) ; z.set_im(2.5) ; Example usage; Result r = 5.0 Result w = (3.0, -1.0) z = (0.0, 2.5)
4) Components of object sent into the method as an “argument”e.g. w 5) Can use a method within a method 3) Components of object invoking the method e.g. Z 1) return type NOT type of left hand operand (i.e. thing on left of + ) Operator overloading Want to be able to do p = z + w ; p = z.operator+(w); p = z + w is shorthand for // Complex addition method complex operator+(complex c) { complex d( re + c.real(), im + c.imag() ) ; return d ; } In “complex.h” 2) complex d temporary/local object for holding result
Private access Cannot be directly accessed from main program Public access Private & Public class complex { private: double re, im ; public: double real() { return re ; } ; }; complex w(3.0,4.0) ; cout << w.re << endl ; Error - won’t compile! cout << w.real() << endl ; Okay
Why make Data Members Private? Can change internals design of class without affecting use in application class complex { private: double r, phi ; public: double real() { return r*cos(phi) ; } ; }; e.g. complex class now stores polar coords cout << w.real() << endl ; Works SAME as before