# C++ ### [Operator Precedence](https://en.cppreference.com/w/cpp/language/operator_precedence) ![](https://i.stack.imgur.com/u3q2E.png) ## Features ### Polymorphism A man at the same time is a father, a husband, and an employee. So ++the same person exhibits different behavior in different situations++. ![](https://media.geeksforgeeks.org/wp-content/uploads/20200703160531/Polymorphism-in-CPP.png =500x) Functions differ in only return type can not be overload. ### Template ```cpp template <class T, class U> class A { T x; U y; public: A() { cout << "Constructor Called" << endl; } }; ``` ### [Preprocessors](https://www.geeksforgeeks.org/cc-preprocessors/) #### 1. Macros There is no semi-colon (;) at the end of the macro definition. ```cpp // macro with parameter #define AREA(l, b) (l * b) int main(){ int l1 = 10, l2 = 5, area; area = AREA(l1, l2); cout << "Area of rectangle is: " << area; return 0; } // multi-line macro #define MACRO(num, str) {\ printf("%d", num);\ printf(" is");\ printf(" %s number", str);\ printf("\n");\ } ``` #### 2. File Inclusion ```cpp // standard directory #include< file_name > // user-defined files #include"filename" ``` #### 3. Conditional Compilation `#ifdef`: single conditional `#if defined(NAME)`: can do compound conditionals ```cpp #if defined(WIN32) && !defined(UNIX) /* Do windows stuff */ #elif defined(UNIX) && !defined(WIN32) /* Do linux stuff */ #else /* Error, both can't be defined or undefined same time */ #endif ``` #### 4. Other directives ```cpp // undefine an existing macro #undef LIMIT ``` ##### `#pragma startup` and `#pragma exit` These directives help us to specify the functions that are needed to run before program startup (before the control passes to main()) and just before program exit (just before the control returns from main()). ```cpp void func1(); void func2(); #pragma startup func1 #pragma exit func2 void func1(){ cout << "Inside func1()\n"; } void func2(){ cout << "Inside func2()\n"; } int main(){ void func1(); void func2(); cout << "Inside main()\n"; // cout result: // Inside func1() // Inside main() // Inside func2() return 0; } ``` ### [Functors](https://www.geeksforgeeks.org/functors-in-cpp/) ### [Lambdas](https://blog.feabhas.com/2014/03/demystifying-c-lambdas/) ![](https://i0.wp.com/blog.feabhas.com/wp-content/uploads/2014/02/image_thumb1.png?resize=454%2C226 =x200) Lambda is compiler-generated, so you must use `auto` for declaration instances of the lambda. ```cpp auto lambd = [](int a){return a*a; }; ``` The lambda function (functor) is only available within the scope of `func()` ```cpp auto lambdOutside = [](int a){return a+2; }; int func(){ vector<int> v(5, 3); // 3, 3, 3, 3, 3 auto lambd = [](int a){return a*a; }; for_each(v.begin(), v.end(), lambd); // OK for_each(v.begin(), v.end(), lambdOutside); // NOT OK } ``` #### Capturing ![](https://i0.wp.com/blog.feabhas.com/wp-content/uploads/2014/02/image_thumb7.png?resize=449%2C338 =400x) ```cpp auto [&](){ /*code...*/ }; // capture everything by reference auto [=](){ /*code...*/ };// capture everything by value ``` #### Lambdas within member functions ==A lambda is a unique (and separate) class of its own== so when it executes it has its own context. ++To capture the class’ member variables we must capture the `this` pointer of the class.++ ```cpp auto lambda = [this](){cout << grid[0][0] << "\n"; } ``` ## Keywords ### [virtual](https://stackoverflow.com/questions/2391679/why-do-we-need-virtual-functions-in-c) Without `virtual` you get "early binding". Which implementation of the method is used gets decided at ++compile time++ based on the type of the pointer that you call through. With `virtual` you get "late binding". Which implementation of the method is used gets decided at ++run time++ based on the type of the pointed-to object - what it was originally constructed as. This is not necessarily what you'd think based on the type of the pointer that points to that object. ```cpp class Animal{ public: virtual void eat() { std::cout << "I'm eating generic food."; } }; class Cat : public Animal{ public: void eat() { std::cout << "I'm eating a rat."; } }; void func(Animal *xyz) { xyz->eat(); } int main(){ Animal *animal = new Animal; Cat *cat = new Cat; func(animal); // Outputs: "I'm eating generic food." // Without virtual func(cat); // Outputs: "I'm eating generic food." // With virtual func(cat); // Outputs: "I'm eating a rat." } ``` ### [static](https://stackoverflow.com/questions/15235526/the-static-keyword-and-its-various-uses-in-c) #### 1. Variables `static` variables exist for the "lifetime" of the scope that it's defined in. #### 2. Functions `static` is often used as a ++class member function++, and only very rarely used for a free-standing function. A static member function differs from a regular member function in that ==it can be called without an instance of a class==, and since it has no instance, it cannot access non-static members of the class. ++Static variables are useful when you want to have a function for a class that definitely absolutely does not refer to any instance members, or for managing static member variables++. ## Standard Template Library (STL) ### [vector](https://cplusplus.com/reference/vector/vector/) #### emplace_back You can perfectly forward the arguments and construct directly an object into a container ++without a temporary at all++. ```cpp Foo x; Bar y; Zip z; v.push_back(T(x, y, z)); // make temporary, push it back v.emplace_back(x, y, z); // no temporary, directly construct T(x, y, z) in place ``` `emplace_back`: [explicit constructor](https://stackoverflow.com/questions/24013545/what-is-the-difference-between-implicit-constructor-and-explicit-constructor) `push_back`: implicit constructor ```cpp std::vector<std::unique_ptr<T>> v; T a; v.emplace_back(std::addressof(a)); // compiles v.push_back(std::addressof(a)); // fails to compile ``` The `{1, 2, 3}` cannot be deduced to `initializer_list<int>` in the following case (which is what the `vector<int>` constructor you want to use expects.) So you need to help it along a bit. ```cpp vector<vector<int>> v; // these two line does the same thing v.push_back({1,2,3}); v.emplace_back(initializer_list<int>{1,2,3}); ``` ### [Iterators](https://www.geeksforgeeks.org/introduction-iterators-c/) ![](https://media.geeksforgeeks.org/wp-content/uploads/C_Iterator_Support.jpg =500x) ![](https://media.geeksforgeeks.org/wp-content/uploads/iteratorOperation.jpg =500x) ### list * Doubly-++linked list++. ==Iterators are valid after modification to the list==. * Non-contiguous memory allocation. * Compared to vector, the list has ++slow traversal++, but ++once a position has been found, insertion and deletion are quick++. #### [splice](https://en.cppreference.com/w/cpp/container/list/splice) Transfers elements from one list to another. ```cpp void splice( const_iterator pos, list& other ); void splice( const_iterator pos, list& other, const_iterator it ); void splice( const_iterator pos, list& other, const_iterator first, const_iterator last ); ``` [[Example code] ](https://onlinegdb.com/5-7mcKRs7) ```cpp list<int> list1 = {1, 2, 3, 4, 5}; list<int> list2 = {10, 20, 30, 40, 50}; auto it = list1.begin(); advance(it, 2); // it point to 3 list1.splice(it, list2); // list1: 1 2 10 20 30 40 50 3 4 5 // list2: // it still point to 3 in list1! list2.splice(list2.begin(), list1, it); // list1: 1 2 10 20 30 40 50 4 5 // list2: 3 ``` ### [priority_queue](https://cplusplus.com/reference/queue/priority_queue/) ![](https://cdn.programiz.com/sites/tutorial2program/files/Introduction.png =300x) Default: max-heap ```cpp priority_queue<int> pq; pq.push(10); pq.push(30); pq.push(20); pq.push(5); pq.push(1); // pq: 30 20 10 5 1 pq.pop(); // pq: 20 10 5 1 ``` * Push, pop complexity: $O(\log n)$ * Min-heap: `priority_queue<int, vector<int>, greater<int> > minHeap;` In case of numeric values, we can multiply the values with -1 and use max heap to get the effect of min heap. ### [equal_range(first, last, val)](https://cplusplus.com/reference/algorithm/equal_range/) Returns the bounds of the subrange that includes all the elements of the range `[first,last)` with values equivalent to `val`. * Time complexity: $O(\log n)$ (binary search twice) ### Generate random number ```cpp random_device rand_dev; mt19937 generator(rand_dev()); uniform_int_distribution<int> distr(range_from, range_to); cout << distr(generator); ``` :::spoiler Don't use `rand()` ![](https://i.imgur.com/MdTn7Lr.jpg =600x) [rand() Considered Harmful](https://learn.microsoft.com/en-us/events/goingnative-2013/rand-considered-harmful) ::: ## Operators ### [Regular cast, static cast, dynamic cast](https://stackoverflow.com/questions/28002/regular-cast-vs-static-cast-vs-dynamic-cast) #### static_cast `static_cast` is used for cases where you basically want to reverse an implicit conversion, with a few restrictions and additions. ```cpp void func(void *data) { // Conversion from MyClass* -> void* is implicit MyClass *c = static_cast<MyClass*>(data); ... } int main() { MyClass c; start_thread(&func, &c) // func(&c) will be called .join(); } ``` In contrast to the C-style cast, the static cast will allow the compiler to check that the pointer and pointee data types are compatible, which allows the programmer to ++catch this incorrect pointer assignment during compilation++. ```cpp char c = 10; // 1 byte int *p = (int*)&c; // 4 bytes *p = 5; // run-time error: stack corruption int *q = static_cast<int*>(&c); // compile-time error ``` #### dynamic_cast Only used to convert object pointers and object references into other pointer or reference types ++in the inheritance hierarchy++. `dynamic_cast` is useful when you don't know what the dynamic type of the object is. It returns a null pointer if the object referred to doesn't contain the type casted to as a base class (when you cast to a reference, a `bad_cast` exception is thrown in that case). ```cpp class MyBase { public: virtual void test() {} }; class MyChild : public MyBase {}; int main(){ MyChild *child = new MyChild(); MyBase *base = dynamic_cast<MyBase*>(child); // ok MyBase *base = new MyBase(); MyChild *child = dynamic_cast<MyChild*>(base); try{ MyChild &child = dynamic_cast<MyChild&>(*base); } catch(std::bad_cast &e){ std::cout << e.what(); // bad dynamic_cast } } ``` ##### Dynamic or static cast The advantage of using a dynamic cast is that it allows the programmer to check whether or not a conversion has succeeded during ++run-time++. The disadvantage is that there is a ++performance overhead++ associated with doing this check. #### const_cast const cast is used mainly when there is a function that takes a non-constant pointer argument, even though it does not modify the pointee. ```cpp void print(int *p) { std::cout << *p; } int main(){ const int myConst = 5; int *nonConst = const_cast<int*>(&myConst); // removes const print(&myConst); // error: cannot convert // const int* to int* print(nonConst); // allowed ... } ``` #### Regular Cast A C-style cast is basically identical to trying out a range of sequences of C++ casts, and taking the first C++ cast that works (combines all of `const_cast`, `static_cast` and `reinterpret_cast`), without ever considering `dynamic_cast`. * Unsigned + signed => unsigned! ```cpp unsigned a = 5; int b = -20; cout << a+b; // 4294967281 ``` ### Read char array (including space) #### C ```c char s[100]; scanf ("%[^\n]s", s); ``` #### C++ ```cpp char s[100]; cin.getline(s, sizeof(s)); ```