350 likes | 530 Views
Practical Session 4. Messages, Instances and Initialization, nested class, C++. Messages. Message - A request for an action from another object Objects perform computation by passing messages between each other
E N D
Practical Session 4 Messages, Instances and Initialization, nested class, C++
Messages • Message - A request for an action from another object • Objects perform computation by passing messages between each other • The sender of a message need only know its interface (arguments and return value(s)) • In a message there is a designated receiver unlike traditional functions • Each receiver might react differently to a message • The fact that the same message can mean two different operations is one form of polymorphism • The reaction to a message can be set at runtime
Event driven message passing • An event driven message is always given to a receiver object • The giver is often called the listener • The receiver send a message to the listener in order to register for an event of interest • The listener will pass a message when the event occurs • The receiver reacts in response to the message • The reaction is determined by the receiver Register for an event E E Act upon event Receiver listener Send message to receiver
interface Clickable {public void onClick(); }interface Overable {public void onOver(); } Exp: Event driven message passing Btn 3 Btn 1 Btn 2 Pseudo code Btn 1 (Clickable, Overable) void onClick() { teeter(); } Void onOver() { makeSound(CashRegister); } Btn 2 (Clickable) void onClick() { spin(); } Btn 3 (Clickable, Overable) void onClick() { makeSound(Drum); } Void onOver() { makeSound(lazer); } Register Send message callRegisteredForClick () { for (Clickable c: clickEventList) c.onClick(); } callRegisteredForOver () { for (Overable o: overEventList) o.onOver(); } Mouse listener registerForClick (Clickable f) { clickEventList.add(f); } registerForOver (Overable f) { overEventList.add(f); } clickEventList btn 1 btn 2 Btn 3 OverEventList btn 1 btn 3
Message passing – C vs. Java • A message can be a function that is passed to another function as a parameter, and can be activated from there • In C, a function pointer(address) is passed as parameter to another function and can be invoked (that is, "called back") as needed. foo() calls g() with the address of f(), g() invokes f() Send a message • Java's interfaces (As seen on previous slide) provide a mechanism by which we can get the equivalent behavior foo() { g(&f); } g(T (*_f)(void)) { _f(…); } T f(…) { … }
void foo(int p) { String str = “abcd”; … } void main() {int I = 1; MyObj head; MyObj tail; foo(15); … } void main() { … head = new MyObj(); tail = new MyObj; … }
Static & Dynamic allocation • In Java all objects are dynamic (accessed by a reference) • In C++ Objects are either static or dynamic (different access methods)
Constructor • The obvious: • Creates an object and prepare it for use • Is called when an object is created - static or dynamic • Initializes the object's data members into a valid state • Can be more than one constructor for a class, with different parameters (Overloading) • Subclass must call, implicit or explicit, superclass constructor in order to initiate superclass data members • If the class doesn’t have a constructor, the compiler provides a default constructor with zero parameters that initiates all data members to default values (0, null, etc…)
Constructor • Not so obvious: • Constructors are NOT inherited • The default constructor is provided implicitly if, AND ONLY IF, no other constructor exists • If a subclass uses the default constructor the superclass must have a 0-arguments constructor (See 6 in previous slide)
Constructors are NOT inherited Assuming constructors can be inherited: public class Sub extends Super {private final String address; Sub(String name, String address){super(name);this.address = address; }public String toString(){// address is null --> throws NullPointerExceptionreturn address.concat(": ").concat(name); }public static void main(String [] args) {// If inherited is allowed the following will // call Super's constructor and address is never initialized!Sub s = new Sub("Yossi"); s.toString(); } } public class Super { public final String name; Super(String name){if (name == null) throw new NullPointerException();this.name = name; }} Using the inherited constructor will cause “address” to be null and crash
The default(empty) constructor is provided implicitly if, AND ONLY IF, no other constructor exists public class Super { } public class Sub extends Super { }// OK - Sub default constructor calls Super default constructor public class Super { } public class Sub extends Super { public Sub(int i) {…} //Constructor }// OK - Sub constructor calls Super default constructor implicitly Super Sub Super Sub Super Sub Super Sub Default constructor Default constructor Default constructor Default constructor public class Super { public Super(int i) {…} //Constructor } public class Sub extends Super { }// Error - Sub default constructor calls Super default constructor but there is no default/empty constructor available in ‘Super’ public class Super { public Super(int rt) {…} } public class Sub extends Super { public Sub(int dt) { } }// Error - Sub constructor needs to explicitly call Super(int) constructor
Canonical class form Default constructor - A constructor that is automatically generated by the compiler in the absence of any other constructors. It is used to calls super() and initiate data members to default values (0, null) Destructor – Release the memory associated with the object delete myObj; Copy constructor – Create a new object and initiate it with the values of the “other” object MyObjmyObj = new MyObj(MyObj other); Copy assignment operator – Copy the values of “other” object to “this” myObj = other; (C++ - Copy assignment) myObj = other; (Java - Assignment only, both objects reference the same object) myObj = other.clone() (java – Note: There is not a copy assignment operator in java, use clone() instead) In C++ the compiler will generate default methods in the absence of progamer-defined methods. Warning – Should be consider carefully since it might cause bugs
Nested/inner class • Nested/inner class • A class that is accessed only by its surrounding classes • Logically grouping classes • Lead to better readable and maintainable code • In java – An inner class is linked to a specific instance and can access its members • In C++ - A nested class is not linked to the outer class but shaded by it • For a java example – See Practical Session 3, undo ex
Introduction to C++ • Method/Data member : • Functions and variables declared within a class. (Same as java) • Free function/variable: • declared outside of a class. It belongs to the global scope. • One should avoid declaring free functions/variables. (Not supported in java) • The main function: • a unique free function – Used as the entry point to the program. (Different from java) • Syntax: int main(intargc, char **argv).
Introduction to C++ • Decleration and definition • A function/class declaration contains only the prototype followed by a semicolon: Function: int foo(int, int); // Free function declaration Class:class Cow { // Class declaration private: int id; public: Cow(int); int getId(); }; • A function definition contains both a prototype and a body. int foo(int a, int b) { return a + b; } // Free function definition Cow::Cow(int _id) { id = _id; } // Class declaration int Cow::getId() { return id; } • One may have multiple declarations of the same function but only one definition in the entire program.
Introduction to C++ • A header file (*.h) • Contains declarations of functions, classes and other identifiers (names). • Contains identifiers that need to be declared in multiply source files. • Header file is included whenever its contents are required by using the #include command. • A C++ source file (*.cpp) • Contains the definitions of the functions and the class methods. • Functions/Classes/methods are not bounded to a specific filename nor they are required to reside at one shared file
Introduction to C++ • include • Syntax:#include <filename> or #include “filename” • Examples: • #include <stdio.h> – paste in the standard library I/O file • #include "my.h" – paste in my.h from the directory of the current file or from a preconfigured path • #include "/user/spl111/Base.h" – paste in a file from absolute path • It Inserts ("copy-pastes“) the contents of filename into the current file. • It has the same purpose as the Java's import command (but a different method) • As a rule: • include only header files (*.h files). • Always start your header file with • #ifndefuniqueName_H_ • #defineuniqueName_H_ • ... //Your declarations here //And end it with #endif
Our first C++ program #ifndefHELLOWORLD_H_ #defineHELLOWORLD_H_ voidprintHello(); //This is a free function declaration #endif include/helloWord.h #include "../include/HelloWorld.h“ //Use hardcoded path #include <iostream> voidprintHello() { std::cout<<"Hello World!" <<std::endl; } src/helloWord.cpp #include "HelloWorld.h“ //The path will be defined at compilation using –I flag int main(intargc, char *argv[]) { printHello(); } src/run.cpp
Hello world in OOP • #ifndefHELLOWORLD_H_ • #defineHELLOWORLD_H_ • class HelloWorld{public: • printHello(); }; • #endif include/helloWord.h #include "../include/HelloWorld.h“ //Use hardcoded path #include <iostream> void HelloWorld::printHello() { std::cout<<"Hello World!" <<std::endl; } src/helloWord.cpp #include "HelloWorld.h“ //The path will be defined at compilation using –I flag int main(intargc, char *argv[]) { HelloWorld hw(); hw.printHello(); } src/run.cpp
I/O cout – standard output stream cin – standard input stream cerr – standard error stream Example #include <iostream> inti= 5; float f = 2.5; char *str = “I’m a c_string”; std::cout<< “i=“ << i << “, f=“ << f << std::endl; std::cout<< “str = “ << str << ‘\n’; Output i=5, f=2.5 Str = I’m a c_string
Pointers Pointers in C++ A pointer is a 4 (or 8) bytes variable that holds an address in thye memory space The operator * int *p_int, j; //defines p_int as a pointer to integer, j as an integer j = *p_int; //Assigns to j the value that p_int points to. The operator &int *p_j = &j; // p_j value is the address of the variable j Example #include <iostream> int j = 5; int *p_j = &j; // p_j gets the address of the variable j std::cout << p_j<< ‘\n’; // prints the address of variable j (0xA3B994AC) std::cout << *p_j << ‘\n’; // prints the value of variable j (5)
Pointers - Example int k = 5; inti = 5; int *p_k = &k;// p_k value is the address of the variable k int *p_k2 = &k;// p_k2 value is the address of the variable k also int *p_i = &i;// p_i value is the address of variable I // Q: True or False? p_k == p_k2 *p_k == *p_k2 &p_k == &p_k2 p_k == p_i *p_k == *p_i True, both p_k and p_k2 hold the address of k True, both p_k and p_k2 point to k False, The address of the variable p_k is different than the adress of p_k2 False, p_k holds the address of k while p_i holds the address of i True, p_k != p_i but k==i therefore the values that p_k and p_i point to are equals
Pointers - Example //pointer to a pointer intnum = 5; int *x = # int **y = &x;
Pointer types and arithmetic • Using different type of pointers in C++ • Type safety • inti = 100; • char *p_i = &i; //Error: cannot convert from 'int *' to 'char *‘ • long l = 200; • short *s = &l; //a value of type "long *" cannot be used to initialize an entity of type "short *" • pointer arithmetic - The operators +, +=, ++, -, -=, --, []p = p+n Increment p by n times <the-size-of-the-element-that-p-points-to> • short sh = 5; • short *p_sh = &sh; • cout << "p_sh = " << p_sh << endl; • p_sh += 1; • cout << "p_sh = " << p_sh << endl; • long l = 5; • long *p_l = &l; • cout << "p_l = " << p_l << endl; • p_l += 1; • cout << "p_l = " << p_l << endl; Adding 1 to a pointer means "make it point to the next element of the same type" p_sh = 0x0044FD08 p_sh= 0x0044FD0A p_l = 0x0044FD10 p_l = 0x0044FD18
Arrays • arr[2] = 9; • Q: Which is equivalent to “arr[2] = 9;” ? • 1. *(arr+2) = 9; • 2. arr+2 = 9; • 3. *arr+2 = 9; • 4. *(arr+9) = 2; Syntax error Syntax error Array out of bounds – Runtime error
Arrays • Arrays are constpointers, can not be changed to point to anywhere else. • point to the start of a memory block on the stack • Contain exactly n elements as declared • Vectors (Collection) are a good alternative for arrays • Example: • intarr[6]; //A memory block for holding 6 integers is allocated on the stack • //arr holds the address of the first element arr=&arr[0] • arr[2] = 9; // The 3rd place in the array is at "the value of arr + 2*sizeof(int)“ • // 0x10 + 2*4 = 0x18
Arrays Regular pointers (vs. const array pointers) can also be used like arrays (Using [] operator) Exp: int *arr, *pi = new int[10]; //Dynamic allocation arr = pi; // Both Arr and pi point to an array of 10 elements. pi[3] = 5; // Accessing the 4th element of the array. pi++; // pi is not const!! now pi points to the second element of A pi[0] = 1; // assign 1 to the second element of A. // Note: Do not forget to free the dynamically allocated array!! delete[] pi; //Bug since pi doesn’t point to the head of the array anymore delete[] arr; //OK
2D Array on the heap • A 2D array on the heap is an array of pointers to arrays. Create it using the following Delete it using the following for (inti = 0; i < rowCount; ++i) delete[] A[i];delete[] A;A = nullptr; introwCount = 4; intcolCount = 3; int** A = newint*[rowCount]; for (inti = 0; i < rowCount; ++i) A[i] = newint[colCount]; Note: This is an array of “pointers to int” To make it clearer use (int*)[rowCount] Stack Heap
c_string (char*) and std::string C_string • The old way of string handling • An array of characters that ends with \0. • Exp: const char *c = "HELLO WORLD" std::cout << c[3] << std::endl; std::cout << &(c[3]) << std::endl; Q: what will be printed? L LO WORLD H E L L O W O R L D \0 • std::string • A class representing a string • Similar to a Java String • c_str() returns a c_string (char*) to the string • Exp: char *cs = s.c_str(); • When using “string” (exp: “abcd”) std::string is created
Try it online! • Cpp online compiler: • https://www.onlinegdb.com/online_c++_compiler • Java online compiler: • https://www.onlinegdb.com/online_java_compiler