Tirgul 2 Agenda Operator overloading revisited friend Static



























- Slides: 27
Tirgul 2 - Agenda �Operator overloading revisited �friend �Static �member �Method �Initialization list
++ operator ++ int i=10; int j=20; cout << i++ << endl; cout << ++j << endl; cout << i << endl; cout << j << endl;
++ Operators: postfix vs. prefix // Prefix: ++n HNum& operator++() { // code that adds one to this HNum return *this; // return ref to curr } flag // Postfix : n++ const HNum operator++(int) calling copy ctor What is this? { Hnum cpy(*this); // code that adds one to this HNum return cpy; }
++ operator ++ �According to the previous slide – what will be the output? int i=10; int j=20; i++=9; ++j=30; cout << i << endl; cout << j << endl; Will not compile error: error C 2106: '=' : left operand must be lvalue
Friend functions �Friend function of a class: �Not a method of the class �Have access to the class’s private and protected data members �Declared inside the class scope �Who chooses his friends? �Used properly does not break encapsulation
Example: Complex revisited. . . //----------------- Why? // friend global IO operators //----------------- friend ostream& operator<< (ostream& os, const Complex& c); friend istream& operator>> (istream& is, Complex& c); //------------------- Why? //------------------- // friend global binary operators //------------------- friend const Complex operator+ (const Complex& c 1, const Complex& c 2); friend const Complex operator* (const Complex& c 1, const Complex& c 2); friend bool operator==(const Complex& c 1, const Complex& c 2); friend bool operator!=(const Complex& c 1, const Complex& c 2); //------------------- };
Example: Complex revisited ostream& operator<< (ostream& os, const Complex& c) { return (os << c. _re << '+' << c. _im << 'i'); } const Complex operator+(const Complex& c 1, const Complex& c 2) { return Complex(c 1. _re + c 2. _re, c 1. _im + c 2. _im); }
Friend classes �A class can allow other classes to access its private data members �The friendship is one sided
friend classes - example Node { private: int data; int key; . . . friend class Binary. Tree; // class Binary. Tree can // now access data // directly }; class Binary. Tree { private: Node *root; int find(int key); }; int Binary. Tree: : find(int key) { // check root for NULL. . . if(root->key == key) { // no need to go through // an accessor function return root->data; } // perform rest of find
Inline functions / methods �A hint to a compiler to put function’s code inline, rather than perform a regular function call. �Objective: improve performance of small, frequently used functions. �An inline function defined in. cpp file is not recognized in other source files. Inserts the code instead of the function address
C vs C++ : macro vs inlining � compare: define SQRT(x) ((x)*(x)). . . SQRT(i++) // unexpected i in the end! �to inline int sqrt(int x) { return x*x; }. . . sqrt(i++) // good behavior
Inline methods � You can hint to the compiler that a method is inline in class declaration: class Tree { . . . size_t size() const { return _size; } }; Implementation in the class scope automatically hints on inline
Inline methods � You can hint to the compiler that a method is inline after class declaration: class Tree { . . . size_t size() const; . . . }; inline size_t Tree: : size() const { return _size; }
Inline vs. Regular Functions / Methods �Regular functions – when called, compiler stores return address of call, allocates memory for local variables, etc. �Code for an inline function is copied into program in place of call – can enlarge executable program, but no function call overhead, hence usually faster execution. �Can enlarge compile time. You compile the inline function again and again in every place it's used.
static class members �As in Java, these are members belonging to the class rather than to an instance. Static function can use only static members // X. h class X { private: static int instances; public: X() { ++instances; } ~X() { --instances; } static int get. Instances() { return instances; } };
static class members �In Java declaration and definition were in the same place �In C++: The data member is declared in class scope, but definition is performed at the cpp file: in the global scope // X. cpp int X: : instances = 0; �in the cpp file, thus avoiding multiple definition in different '. o' files
static class members �Does not have to be initialized at definition, but in this course you have to initialize it. int X: : instances; // bad style
static class function �Example of using a static function: // Example of using a static function: X x 1, x 2; std: : cout << X: : get. Instances() << std: : endl; std: : cout << x 1. get. Instances() << std: : endl;
static const class members // X. h class X { private: static const int C= 42; static const std: : string STR; . . . }; // X. cpp const std: : string X: : STR("labcpp"); Possible only with const integral types
Initialization List
The default ctor int main() { B b; � class A { public: A() � { std: : cout << � "A - default � ctorn"; } }; class B { A _a 1, _a 2; public: B() { std: : cout << "B default ctorn"; } }; // output A – default ctor B - default ctor
Class with object members int main() { B b; � class A class B { A _a 1, _a 2; public: B() { std: : cout << "B default ctorn"; } }; { public: A(int a) � { std: : cout << � "A ctor with one � parametern"; } � }; // compilation error No default ctor for _a 1, _a 2
int main() { B b (2, 3); The initialization list � class A { public: A(int a) � { std: : cout << � "A (" << a << ") " << std: : endl; } }; class B { A _a 1, _a 2; public: B(int i, int j) : _a 1 (i), _a 2(j) { std: : cout << "B cons" << std: : endl; } }; // output A (2) A (3) B cons
The initialization list Initialization of object members. 2. Initialization of constants and reference variables. 3. In the future: Initialization of parent class. 4. It is faster and safer to use the initialization list than initialization in the constructor 1.
Initialization of const and ref. � class A { int& _a; const int _b; public: A(int a); }; A: : A(int a) { _a = a; _b = 5; } // compilation error Const and ref vars must initialized in their declaration class A { int& _a; const int _b; public: A(int a); }; A: : A(int a) : _a (a), _b (5) { }
Initialization using pointers (1) int main() { B b (2); � class A { public: A(int a); }; A: : A(int a) { std: : cout << "A (" � << a << ")" << endl; class B { A *_a 1; public: B(int i); }; B: : B(int i) { _a 1 = new A (i); cout << "B consn"; } // output A (2) B cons
Initialization using pointers (2) int main() { B b (2); � class A { public: A(int a); }; A: : A(int a) { std: : cout << "A (" � << a << ")" << endl; class B { A *_a 1; public: B(int i); }; B: : B(int i): _a 1 (new A (i)) { cout << "B consn"; } // output A (2) B cons