C Review What Have We Learned C Basic

C++ Review

What Have We Learned? C: �Basic language �Motto: “Simple does it” �Lean (& mean) C++ �High level constructs �Complex type system �Extensive library �Motto: Complex and powerful 2

References and Const in C++ the common idiom is to pass objects using references void foo( /* input */ const My. Class& a, /* output */ My. Class& b) { … } 3

reference variables int i = 5; int &c = i; Must be initialize in the declaration line (initialization list for ctors). // example for bug (the same can occur with // pointers): int& foo() { int i = 3; return i; } 4

Overload resolution 1. Find all functions with same name “candidates”. Let’s call them Ω 1 2. Find Ω 2⊆Ω 1 which have the correct number of arguments - “viable candidates” 3. Find Ω 3⊆Ω 2 the best viable functions: Those whose parameters all have either better or equalranked implicit conversion sequences than all of the other viable functions. if |Ω 3|=1: use that function else (0 or more than 1): emit compilation error

Overload resolution (!) double Add( int, double); double Add( double, int x=4); double Add( double, double); Add( 1, 4); //Compile Error Add( 1, 1. 5); //OK Add( 1. 2, 1. 5); //OK Add( 1) //OK Add( 1. 2) 1. 2. 3. 4. 6 //OK Conversion (example) Rank No Conversion Array to pointer Non const to const Exact (1) float to double char to int Promotion (2) double to float to int Conversion (3) User defined conversion Conversion (4) Default parameters count as supplied The rank of a chain of conversions is the rank of highest link Two overloads with same rank – ambiguous and compile error Inheritance & Templates add complexity

Overload resolution void func(int, double) { std: : cout << 1 << std: : endl; } void func(int, double, double) { std: : cout << 2 << std: : endl; } int main() { func(1, 2, 3, 4); } 7 1 will be printed

Overload resolution void func(double, int, double) { std: : cout << 3 << std: : endl; } void func(int, double, double) { std: : cout << 2 << std: : endl; } int main() { func(1, 2, 3, 4); } 8 ambiguous

Simple Class Declaration Counter. h #ifndef _COUNTER_H_ #define _COUNTER_H_ class Counter { public: Counter(); // Constructor void increment(); // A method int value(); // Another one private: int _count; }; #endif // _COUNTER_H_ 9

Class Basics - member/static class List { public: static int get. Max. Size(); int get. Size(); static int max_size=1000; //error! (only outside, below) int _size=0; //error! (only in ctor, coming slides) }; int List: : max_size=1000 //ok. int main() { List l; l. get. Size(); List: : get. Max. Size(); l. get. Max. Size(); } 10 OK with C++11
![Overloading the bracket operator class Array { private: int _array[3]; public: Array(int array[3]); int& Overloading the bracket operator class Array { private: int _array[3]; public: Array(int array[3]); int&](http://slidetodoc.com/presentation_image_h2/7fdc848c3d4a50cd8b9f343cd32beb63/image-11.jpg)
Overloading the bracket operator class Array { private: int _array[3]; public: Array(int array[3]); int& operator[] (const index); }; int& Array: : operator[] (const index) { return _array[index]; }
![Overloading the bracket operator int main() { int array[3] = {0, 1, 2}; Array Overloading the bracket operator int main() { int array[3] = {0, 1, 2}; Array](http://slidetodoc.com/presentation_image_h2/7fdc848c3d4a50cd8b9f343cd32beb63/image-12.jpg)
Overloading the bracket operator int main() { int array[3] = {0, 1, 2}; Array arr(array); arr[2] = 3; cout << arr[2]; // set a value // get a value const Array const. Arr = {1, 2, 3}; cout << const. Arr[2] //compilation error return 0; }
![Overloading the bracket operator – const version class Array { private: int _array[3]; public: Overloading the bracket operator – const version class Array { private: int _array[3]; public:](http://slidetodoc.com/presentation_image_h2/7fdc848c3d4a50cd8b9f343cd32beb63/image-13.jpg)
Overloading the bracket operator – const version class Array { private: int _array[3]; public: Array(int array[3]); int& operator[] (const index); int operator[] (const index) const; };

C-tors, D-tors, memory management 1. C-tors: initialization 2. D-tors: Ensure propose “cleanup” when the object is destructed - freeing memory, notifying related objects, etc. 3. new: 1. Allocates memory 2. Calls c-tor 3. Returns pointer to the object 4. delete: 1. Calls d-tor 2. Frees memory 14

C-tor & D-tor order of execution 1. Constructor of the base class is executed 2. Members are constructed. 3. Constructor of the class itself is executed. Destruction is done in the opposite order. 15

Default c-tor • Will this compile? • Will this link? MIL C-tors, d-tors order class A { A(int x, int y){} }; void main() { A d; } class A { public: • Will this compile? • Will this link? 16 A(int x=9, int y=900); }; void main() { A d; }

Don’t forget the base 17 class A { public: int _a; A () : _a (5) { } A (const A &src) : _a (src. _a) { } }; class B: public A { public: int _b; B () : _b (3) { } B (const B &src) : _b (src. _b){} }; int main () { B b; b. _a = 2; B c = b; //copy ctor std: : cout << c. _a << std: : endl; } // output 5

Don’t forget the base 18 class A { public: int _a; A () : _a (5) { } A (const A &src) : _a (src. _a) { } }; class B: public A { public: int _b; B () : _b (3) { } B (const B &src) : A (src), _b (src. _b){} }; int main () { B b; b. _a = 2; B c = b; //copy ctor std: : cout << c. _a << std: : endl; } // output 2

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 19 class A { int& _a; const int _b; public: A(int a); }; A: : A(int a) : _a (a), _b (5) { } OK

Copy c-tor problem class Base { public: int *p; Base () : p (new int(0)) {} ~Base () { delete p; } }; void foo (Base b) { (*(b. p))++; }; 20 int main () { Base b; foo (b) *(b. p) = 3; //seg fault }; What is wrong here?

Solution • Always pass by reference • Declare copy c-tor and operator= as private • Don’t implement them OR • Implement your own: • copy c-tor • operator= • D-tor 21

Implicitly defined functions In total – we have 4 implicitly defined functions: 1. Default constructor 2. Copy constructor 3. operator= 4. Destructor If you define of them manually – you take all responsibility, e. g. : • For ctor – call the correct base ctor. • For operator= check self assignment. 22

Inheritance • The main ideas are similar to what you already know from Java • C++ has no interfaces but it allows multiple inheritance Class A • Access modifiers • public • protected • private • Can be applied to: • Members • Inheritance 23 Class B Boo! Class D Class C

Calling Base methods class B { public: void f() { cout << "B: : f()n"; } }; class D: public B{ public: void f() { cout << "D: : f()n"; } }; int main(int argc, const char * argv[]) { D d; D: : f() d. f(); B: : f() d. B: : f(); d. D: : f(); D: : f() return 0; } 24

Types of inheritance A base class also has an access modifier: class Programmer : public Person class Programmer : private Person class Programmer : protected Person private/protected inherence: • Everything declared in Person is private/protected when used from Programmer • Inside programmer you can access Person members according to Person’s modifiers • Users of programmer won't have access to Person members 25

Public inheritance 26 Base access modifier Derived class access? Public Yes Private No No Protected Yes No

Private inheritance Base access modifier Derived class access? Public Private Yes No Private No No Protected Private Yes No class Base { public: int m_n. Public; private: int m_n. Private; protected: int m_n. Protected; }; class Pri: private Base { Pri() { m_n. Public = 1; // okay m_n. Private = 2; // not okay m_n. Protected = 3; // okay } }; 27 int main() { Pri c. Pri; c. Pri. m_n. Public = 1; // not okay c. Pri. m_n. Private = 2; // not okay c. Pri. m_n. Protected = 3; // not okay return 0; }

Protected inheritance 28 Base access modifier Derived class access? Public Protected Yes No Private No No Protected Yes No

objects – no polymorphism class Base { public: int i; void foo() { cout <<"base"<<endl; } }; class Derived : public Base { public: void foo() { cout <<"derived"<<endl; } }; 29 int main () { Derived d; d. foo(); Base &b = d; b. foo(); }; // output derived base

objects – polymorphism! class Base { public: int i; virtual void foo() { cout <<"base"<<endl; } }; class Derived : public Base { public: void foo() { cout <<"derived"<<endl; } }; 30 int main () { Derived d; d. foo(); Base &b = d; b. foo(); Base c = d; c. foo(); }; // output derived base

Static resolution Circle* circle = new Circle(1, 1, 2); Square* square = new Square(2, 2, 1); Shape* My. Shapes[2]; My. Shapes[0] = circle; My. Shapes[1] = square; circle->Draw(); square->Draw(); My. Shapes[0]->Draw(); My. Shapes[1]->Draw(); 31 // // Calls Circle: : Draw() Square: : Draw() Shape: : Draw()

Pointing to an Inherited Class class Derived b; class Base* p = &b; When using *p, we treat b as though it was a Base object In the general case the compiler cannot know if *p is from a derived class or not 32 p: b: _x _a _z

Example class A { public: virtual void int _a; }; class B: public { public: virtual void f 4(); int _b; }; A a 1, a 2; B b; 33 void A: : f 1 { f 1(); f 2(); A f 1(); f 3(); //. . . }; a 1: <vtbl> _a a 2: <vtbl> _a b: <vtbl> _a _b VTBLs A void A: : f 2 { //. . . }; f 1 f 2 B f 1 f 2 f 3 void B: : f 1 { //. . . }; void B: : f 3 { //. . . };

Copy & Inheritance class A { public: virtual void int _a; }; class B: public { public: virtual void f 4(); int _b; }; f 1(); f 2(); A f 1(); f 3(); A a; B b; a = b; a. f 1() //calls A: : f 1()!!! 34 The assignment operator doesn't know that the function parameter is of class B, since it was up-casted A f 1 f 2 B "slicing" a: <vtbl> _a VTBLs f 1 f 2 f 3 b: <vtbl> _a _b

Some of polymorphism technicalities: • Using vtbl is slower than regular functions • Don’t use it if you don’t need • Don’t use virtual functions in the base ctor • Don’t forget to define the dtor as virtual when it’s needed 35

class A { public: A() { fn(); } virtual void fn() { _n = 1; } int getn() { return _n; } protected: int _n; }; class B : public A { public: B() : A() {} virtual void fn() { _n = 2; } }; main() { B b; int n = b. getn(); } 36

Diamond Multiple Inheritance • Declare virtual to get one copy of the upper base class: struct A { int a; }; struct B 1 : public virtual A struct B 2 : public virtual A struct C 1: public B 1, public B 2 int main() { C 1 c; c. B 1: : a=0; c. B 2: : a=2; //same variable } 37 { }; as above!

Templates – compile time polymorphism inline template <class T> T max (T a, T b) // output { 5 return (a > b ? a : b); 7. 2 } int main () { cout << max (3, 5) << endl; cout << max (3. 5, 7. 2) << endl; } 38

Templates – compile time polymorphism template <class T> T max (T a, T b) { return (a > b ? a : b); } int max (int a, int b) { cout << "int function" << endl; return (a > b ? a : b); } int main () { cout << max (3, 5) << endl; cout << max (3. 5, 7. 2) << endl; } 39 // output int function 5 7. 2 Think of it as a two stage process

Templates & Compilation • A template is a declaration • The compiler performs semantics checks only when a template is instantiated with specific arguments, then the generated code is compiled. Implications: 1. Template code has to be visible by the code that uses it (i. e. , appear in. h file) 2. Some compilation errors can occur only in a specific instance 40

Template specialization template <class Type> class A { int main() { public: A<int> ai(5); Type _data; A<char*> as("hi"); A(Type data) : _data(data) { } bool is. Bigger(Type data); ai. is. Bigger(7); }; //generic is. Bigger() template <class Type> as. is. Bigger("bye"); bool A<Type>: : is. Bigger(Type data) { //specific is. Bigger() return data > _data; } } template <> bool A<char*>: : is. Bigger(char *data) { return strcmp(data, _data) > 0; } 41

Use example – select best algorithm in compile time template <int Convertable> struct Copy. Algorithm { template <class T, class U> static void do. Copy(vector<T>& t, vector<U>& u) { auto J=u. begin(); auto I=t. begin(); for(; I!=t. end(); ++I, ++J) *I=*J; } }; template <> struct Copy. Algorithm<0> { template <class T, class U> static void do. Copy(vector<T>& t, vector<U>& u) { } }; template< class T , class U> void copy( vector<T>& t, vector<U>& u ) { Copy. Algorithm<is_convertable < T, U >: : exists>: : do. Copy(t, u); } class A { }; int main() { vector<int> vi; vector<double> vd; vector<A> va; copy(vd, vi); copy(vi, va); return 0; 42 }

Important point about exceptions struct B { B() {cout << "in B's c-tor" << endl; } ~B() {cout << "in B's d-tor" << endl; } }; struct A : public B { A() {cout << "in A's c-tor" << endl; } ~A() {cout << "in A's d-tor" << endl; } }; void main() { try { A a; throw(2); } catch (. . . ) { } } 43

auto_ptr • Wraps any pointer • Automatically deleted when we leave the scope (d-tor executed) • part of the standard library My. Class* f(. . . ) { auto_ptr<My. Class> p(new My. Class()); . . . return p. release(); //Sets the auto_ptr internal pointer to null pointer without destructing the object currently pointed by the auto_ptr } If an exception occurs prior to return, the instance of My. Class will be automatically deleted by p’s destructor. After auto_ptr is copied (to another one) it points nowhere. 44

auto_ptr => unique_ptr • auto_ptr is depricated • replaced by unique_ptr in c++11 – gives ownership errors in compile time (no operator=) • Can be used in stl containers • Uses move semantics and rvalue reference • You can read more at: http: //www. informit. com/guides/content. aspx? g=cplus&seq. Num=400 45

The Three Basic Rules of Operator Overloading in C++ • Whenever the meaning of an operator is not obviously clear and undisputed, it should not be overloaded • Always stick to the operator’s well-known semantics: • • Always provide all out of a set of related operations: • 46 E. g. don’t overload + for subtraction E. g. If you overload a++ you should probably also overload ++a

std: : shared_ptr • Uses "shared memory semantics" – (i. e. , in most cases – reference counting). • In addition to pointing to the object all instances keep a pointer to a counter. • The counter is: • Increased on creation • Increased on copy • Decreased on delete • When counter reaches 0 the destructor is called. 47

c++ style casting There are four casting operators: �static_cast<type>(expression) �const_cast<type>(expression) �reinterpret_cast<type>(expression) �dynamic_cast<type>(expression) 48

C-style cast C casts are casts using (type)object Or type(object) A C-style cast is defined as the first of the following which succeeds: const_cast static_cast then const_cast reinterpret_cast, then const_cast 49

RTTI : typeid operator • Obtains info about an object/expression usage: typeid(obj ) Example: Dog d; Cat c; cout << "d is a " << typeid(d). name() << ", c is a " << typeid(c). name() <<endl; Output: d is a Dog, c is a Cat 50

lambda functions int main() { array<int, 5> ar = {1, 2, 3, 4, 5}; int sum=0; for_each(ar. begin(), ar. end(), [&](int i) { sum+=i; }); } template<class iter, class fn> void for_each(iter b, iter e; fn f) { for (; b != e; ++b) {f(*b); } } 51

Move ctor using rvalue reference - && My. String(My. String&& that) { _length = that. _length; _data = that. _data; that. data = nullptr; // the safer c++11 choice for NULL } Inside that constructor we can do anything we want with the source, as long as we leave it in some valid state When will this ctor be used (remember function overloading resolution)? 52

C++11 auto • range-based loops • Smart-pointers • Lambda functions • Rvalue references and move semantics • nullptr • Delegating constructors, class member initialization And much more than we spoke about • 53 • Use –std=c++11 when needed • Now the committee is working on c++14 (smaller changes in comparison to c++11)

auto int main() { string str; cout << "Please enter your name"; cin >> str; for (auto c: str) { cout << c << ", "; } std: : cout << "n"; What is the type of c? return 0; } 54
![Lambda functions Lambda function’s syntax: [capture clause] (parameters) -> return-type {body} Unlike an ordinary Lambda functions Lambda function’s syntax: [capture clause] (parameters) -> return-type {body} Unlike an ordinary](http://slidetodoc.com/presentation_image_h2/7fdc848c3d4a50cd8b9f343cd32beb63/image-55.jpg)
Lambda functions Lambda function’s syntax: [capture clause] (parameters) -> return-type {body} Unlike an ordinary function, which can only access its parameters and local variables, a lambda expression can also access variables from the enclosing scope(s). Such a lambda is said to have external references. [=] //capture all of the variables from the enclosing scope by value [&]//capture all of the variables from the enclosing scope by reference 55

Lambda example vector <Employee> emps {{"Josh”, 2100. 0}, {"Kate”, 2900. 0}, {"Rose”, 1700. 0}}; const auto min_wage = 1600. 0; const auto upper_limit = 1. 5 * min_wage; //report which accountant has a salary that is within a specific range std: : find_if(emps. begin(), emps. end(), [=](const Employee& a) { return a. salary()>=min_wage && a. salary() < upper_limit; } ); 56
, strs. end(), [](string](http://slidetodoc.com/presentation_image_h2/7fdc848c3d4a50cd8b9f343cd32beb63/image-57.jpg)
Lambda example vector<string> strs = {"Anna", "Beth", "Carl", "David"}; for_each(strs. begin(), strs. end(), [](string i){cout << i << ", "; }); 57
![Lambda: factorial int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, Lambda: factorial int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9,](http://slidetodoc.com/presentation_image_h2/7fdc848c3d4a50cd8b9f343cd32beb63/image-58.jpg)
Lambda: factorial int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; auto factorial = [](int i, int j) {return i * j; }; long res = std: : accumulate(arr, arr+12, 1, factorial); cout<<"12!="<<res<<endl; // 479001600 58

Question Is the next expression correct? ((i < 3) ? i : j) = 7; Is the left operand an rvalue or an lvalue? 59

STL - Main Components (concepts) Function Objects Adaptors Streams Strings 60 Iterators Containers Algorithms

Exam class The exam will take place on Thursday Sep. 18 th at 9 am לוין 8: א - ח מתמטיקה 2: ט - כ + תוספת זמן כימיה 7: ל - ת 61


See you in the exam (moed a) Prepare well ! 63
- Slides: 63