├── .gitignore ├── 01. Introduction ├── 01. Intro to the course.md └── 02. Installing IDEs.md ├── 02. C++ Basics ├── 01. first.cpp ├── 02. data_types.md ├── 03. size_data_types.cpp ├── 04. var_literals.cpp ├── 05. overflow.cpp ├── 06. Operators And Expressions.md ├── 07. expressions.cpp ├── 08. compound_operators.cpp ├── 09. pre_post_inc_dec_operators.cpp ├── 10. bitwise_operators.cpp ├── 11. enum_typedef.cpp └── 12. salary.cpp ├── 03. Conditional Statements ├── 01. if_statement.cpp ├── 02. dynamic_declaration.cpp ├── 03. switch_case.cpp ├── 04. switch_case_calculator.cpp ├── 05. bill_discount_calculator.cpp └── 06. leap_year.cpp ├── 04. Loops ├── 01. Loops.md ├── 02. display_numbers.cpp ├── 03. sum_n_natural_numbers.cpp ├── 04. multiplication_table.cpp ├── 05. factorial.cpp ├── 06. find_factors.cpp ├── 07. prime_number.cpp ├── 08. display_digits_of_a_number.cpp ├── 09. sum_of_digits_of_a_number.cpp ├── 10. gcd.cpp └── 11. palindrome.cpp ├── 05. Arrays ├── 01. Arrays.md ├── 02. array.cpp ├── 03. sum_of_array.cpp ├── 04. nested_for_loop.cpp ├── 05. patterns.cpp ├── 06. matrix.cpp ├── 07. average_of_array.cpp └── 08. mat_multiplication.cpp ├── 06. Pointers ├── 01. Pointers.md ├── 02. pointer_sample.cpp ├── 03. heap_memory.cpp ├── 04. dynamic_mem_allocation.cpp ├── 05. Pointer Arithmetic.md ├── 06. pointer_arithmetic.cpp ├── 07. Problems Using Pointers.md ├── 08. Reference.md ├── 09. reference.cpp └── 10. pointer_to_function.cpp ├── 07. Functions ├── 01. functions.cpp ├── 02. max_of_3.cpp ├── 03. function_overloading.cpp ├── 04. function_template.cpp ├── 05. default_arguments.cpp ├── 06. pass_by_value.cpp ├── 07. pass_by_address.cpp ├── 08. pass_by_reference.cpp ├── 09. return_by_address.cpp ├── 10. return_by_address.cpp ├── 11. return_by_reference.cpp ├── 12. local_global_variable.md ├── 13. scoping_rule.cpp ├── 14. static_variables.cpp ├── 15. recursive_function.cpp └── 16. linear_search_function.cpp ├── 08. Intro to OOP ├── 01. Introduction.md ├── 02. class_creation.cpp ├── 03. pointer_to_object.cpp ├── 04. Philosophy Behind Data Hiding.md ├── 05. accessor_mutator.cpp ├── 06. constructors_philosophy.cpp ├── 07. deep_copy_constuctor.cpp ├── 08. function_in_class.cpp ├── 09. scope_resolution.cpp ├── 10. this_pointer.cpp ├── 11. struct_class.cpp └── 12. student_exercise.cpp ├── 09. Operator Overloading ├── 01. operator_overloading.cpp ├── 02. friend_operator_overloading.cpp ├── 03. insertion_operator_overloading.cpp └── 04. rational_class_exercise.cpp ├── 10. Inheritance ├── 01. inheritance.cpp ├── 02. inheritance.cpp ├── 03. constructors_in_inheritance.cpp ├── 04. isA_hasA_relation.md ├── 05. access_specifier.cpp ├── 06. access_specifier.cpp ├── 07. types_of_inheritance.md ├── 08. Ways of Inheritance.md ├── 09. inheritance_method.cpp ├── 10. Generalization vs specialization.md └── 11. student_exercise.cpp ├── 11. Base Class Pointer Derived Class Object ├── 01. Base Class Pointer Derived Class Object.md ├── 02. base_class_ptr_derived_class_object.cpp ├── 03. base_ptr_der_object.cpp └── 04. base_class_ptr.cpp ├── 12. Polymorphism ├── 01. function_overriding.cpp ├── 02. virtual_functions.cpp ├── 03. virtual_functions.cpp ├── 04. polymorphism.cpp ├── 05. abstract_class.cpp ├── 06. abstract_class_2.cpp └── 07. Student Exercise.cpp ├── 13. Friend and Static Member ├── 01. friend_function.cpp ├── 02. friend_classes.cpp ├── 03. static_members.cpp ├── 04. static_example.cpp ├── 05. static_members_example.cpp └── 06. inner_nested_class.cpp ├── 14. Exception Handling ├── 01. exception_handling_intro.cpp ├── 02. exception_handling.cpp ├── 03. exception_handling_in_functions.cpp ├── 04_throw.md ├── 05_throw.cpp ├── 06_catch_multiple.cpp └── 07_stack.cpp ├── 15. Template Functions and Classes ├── README.md ├── stack_int.cpp └── template_stack.cpp ├── 16. Constants Preprocessors or Directives and Namespaces ├── README.md ├── const0.cpp ├── const1.cpp ├── const2.cpp ├── const3.cpp ├── const4.cpp ├── const5.cpp ├── const6.cpp ├── const7.cpp ├── const8.cpp ├── macro0.cpp └── namespace0.cpp ├── 17. Destructors and Virtual Destructors ├── README.md ├── destructor.cpp └── virtual_destructor.cpp ├── 18. IO Streams ├── README.md ├── read0.cpp ├── serialization.cpp ├── serialization.txt ├── write0.cpp └── write0.txt ├── 19. STL ├── README.md ├── list.cpp ├── map.cpp ├── stl.cpp └── vector.cpp ├── 20. C11 ├── README.md ├── auto.cpp ├── ellipsis.cpp ├── ellipsis2.cpp ├── final.cpp ├── lambda.cpp └── unique_ptr.cpp ├── 21. Project - Banking System ├── Bank.data ├── README.md └── main.cpp ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | .vscode/* 34 | 35 | .idea/* 36 | !Makefile 37 | .vscode/* 38 | .vscode/settings.json 39 | .vscode/tasks.json 40 | .vscode/launch.json 41 | .vscode/extensions.json 42 | ##### Qt 43 | # C++ objects and libs 44 | *.slo 45 | *.lo 46 | *.o 47 | *.a 48 | *.la 49 | *.lai 50 | *.so 51 | *.dll 52 | *.dylib 53 | *.mod 54 | *.smod 55 | 56 | # Compiled Static libraries 57 | *.lai 58 | *.la 59 | *.a 60 | *.lib 61 | 62 | # Executables 63 | *.exe 64 | *.out 65 | *.app -------------------------------------------------------------------------------- /01. Introduction/01. Intro to the course.md: -------------------------------------------------------------------------------- 1 | # Intro to course 2 | -- We will be learning all that is part of standard university one semester course in C++. Course medium by Udemy instructor is White Board and screenrecording from time to time. I will be writing whatever I feel is important in these notes. Demonstration of each topic along with code will be provided, to cover practical and theoretical aspects in a greater way for learning as well as remembering for longer periods of time has been taken care of. 3 | 4 | # Why one should learn C++ ? 5 | 6 | 1. It is in your syllabus and is widely used even today due to its large applications, as well as lots and lots of legacy code is also written on C++ already, so it is an integral part of many crucial systems we see today. 7 | 2. C++ follows Object Oriented Paradigm, lots of new languages are Object Oriented and it it provides lots of features in Object Oriented which are not available in newer languages and syntactically it is much better, even if that means you have to learn a lots of things due to sometimes exhaustive syntax. Which plays a crucial role in giving programmers more power and freedom over writing code in the way they want. 8 | 3. C++ is compatible with hardware due to it's nature of being a low level language which is easier for computers to understand. Proving to be a great choice for making Apps which run directly over the OS. So here is a layer of Hardware >> OS >> Application. 9 | 4. Looking at applications such as DotNet, C#, Java or Python, these languages do not run dierctly over the OS but instead they need an interpreter that is a run time environment like java runs inside JVM and .NET programs run inside Common Language Run-time environment CLR. 10 | So, interpreter is used to establish interaction between OS and Hardware which makes it as follows (Hardware >> OS >> Environment >> App) due to this intermediate interference of environment layer these languages aren't that powerful compared to C++ which directly interacts with OS or hardware. 11 | 12 | ## List of applications of C++ 13 | 1. System Softwares/Tools 14 | 2. Embedded Systems (Microprocessors & Controllers viz. Arduino,Rasp) 15 | 3. Operating Systems, Interpreters 16 | 4. Platforms and Engines 17 | 5. Games & Graphics 18 | 19 | # About Course : Contents we will be covering 20 | 21 | Course is around 20+ hours, there are 200+ lectures with 21 or so sections currently. 22 | ## Contents : Outline 23 | 1. Introduction 24 | 2. C++ Basics 25 | 3. Conditional Statements 26 | 4. Loops 27 | 5. Functions 28 | 6. Object-Oriented Programming 29 | 7. Operator Overloading 30 | 8. Templates 31 | 9. I/O Streams 32 | 10. STL 33 | 11. Features of C++ 34 | 35 | # Course Flow 36 | We will be focusing on basics and being correct syntax wise throughout the course but it will be more intense till we get to functions, after that point the focus will shift to understanding OOP concepts and connecting them with real world examples to understand how it fits in software development cycle. -------------------------------------------------------------------------------- /01. Introduction/02. Installing IDEs.md: -------------------------------------------------------------------------------- 1 | # For Windows 2 | 3 | 1. Go to [MinGW](http://www.mingw.org/) >> Click on Downloads and get the compiler from sourceforge website. 4 | Install the compiler and set the path to it in System Variables so it can be detected by any programs that want to use it. 5 | 6 | 2. Other choice is to use **Code::Blocks** 7 | [Code::Blocks IDE Download Link](http://www.codeblocks.org/downloads/26) 8 | Click on Download Binary Release and I would recommend going for *mingw-setup.exe file as it would download compiler as well as IDE. Again download it from sourceforge and install it. Do, a spouse mode installation, agree, yes, yes next agree install. xD Wait for the installation to finish. 9 | 10 | Open Code::Blocks select new project and console application of C++ and press next, enter project name and Finish. 11 | Build the project by clicking build and see how the main.cpp is executed in console. That's it. Your installation of C++ IDE works. 12 | 13 | 3. **DevC++** : Go to [this link](https://www.bloodshed.net/dev/devcpp.html) to download and install DevC++. 14 | Be sure to choose whether you want without compiler or with MinGW installed or source code variant. 15 | Again Install the program, create new project of console application type. Try Hello World program in main.cpp, try building the project to verify if it works. 16 | 17 | # For Mac OS X 18 | 19 | Go to App Store and search for Xcode. Install it and you're done. 20 | Alternatively, you can also go to terminal and type **xcode-select --install** 21 | 22 | Create new XCode Project >> Command Line Tool >> Select language as C++ and give title and destination and proceed. 23 | -------------------------------------------------------------------------------- /02. C++ Basics/01. first.cpp: -------------------------------------------------------------------------------- 1 | #include // Including library in the program 2 | using namespace std; // Allows programmer to use anything inside std namespace without using std 3 | // More on namespaces later 4 | /* 5 | int main() // Starting point of the program 6 | { 7 | cout<<"Hello World!\n"; // Using << insertion operator and enclosing string in double quotes "" 8 | return 0; // Since written in int therefore returns 0 at the end as it shows successful completion. 9 | // \n and \t are esscape sequences, specifically these two for new line and tab space respectively. 10 | } 11 | */ 12 | 13 | // To add two numbers 14 | /* 15 | int main() 16 | { 17 | int a,b,sum; // Declaring 3 variables called a, b and sum 18 | cout<<"Enter two numbers : \t" // Prompt for user to be displayed on console window 19 | cin>>a>>b; // Extraction operator to read user input from keyboard and assigning it to a and b 20 | sum = a+b; 21 | cout<<"Sum is : "<>str; 34 | cout<<"Hello "< 2 | using namespace std; 3 | int main() 4 | { 5 | char x; 6 | int a; 7 | float b; 8 | long c; 9 | double d; 10 | long double e; 11 | cout<<"Size of char is : "< 12 | using namespace std; 13 | int main(int argc, char const *argv[]) 14 | { 15 | char x = 127; 16 | cout << "Value initialised to x = " << (int)x << endl; // Displaying the int value of char x 17 | cout << endl; 18 | char y = 128; 19 | cout << "As we keep char y to 128 we are expecting -128 and what we get is : " << (int)y << endl; 20 | cout << endl; 21 | cout << "Trying to do value overflow on x now : " << endl; 22 | cout << endl; 23 | cout << "\t\tValue before Overflow : " << (int)x << endl; 24 | cout << endl; 25 | x++; 26 | cout << "\t\tValue after increment when we are expecting it to get overflown and be -128 is : " << (int)x << endl; 27 | int a = INT32_MAX; // Maximum integer in a 32-bit system 28 | int b = INT32_MIN; // Minimum integer in a 32-bit system 29 | cout << "Maximum integer in a 32-bit system a = " << a << endl; 30 | cout << "Minimum integer in a 32-bit system b = " << b << endl; 31 | a++; 32 | cout << "Value of a after post increment = " << a << endl; 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /02. C++ Basics/06. Operators And Expressions.md: -------------------------------------------------------------------------------- 1 | # Operators And Expressions 2 | 3 | ## Arithmetic Operators : 4 | 5 | In arithmetic operators \*,/,% have higher precedence as compared to +,-. 6 | 7 | **%** : Gives Remainder 8 | e.g. 34%4 = 2, 39%12 = 3 9 | 10 | **/** : Gives Quotient 11 | e.g. 34/4 = 8, 39/12 = 3 12 | 13 | #### NOTE : If a = 12.5f and b = 6.1f then suppose we have c = a/b then it is correct and we will get the output but mod % operator won't work for c = a%b. % works only on int and char type data and not for float. 14 | 15 | ## Preparing Expressions using Operators 16 | 17 | Say we have an expression k = a+b+c\*d and we want expression to be such that c and d are multiplied and then product is added with sum of a and b. Here comes the precedence rule PEMDAS : 18 | **P** = Parentheses 19 | **E** = Exponents 20 | **M** = Multiplication 21 | **D** = Division 22 | **A** = Addition 23 | **S** = Subtraction 24 | 25 | So, instead it would be much better to put parentheses such as k = ((a+b)+(c*d)), but this isn't easily readable and frankly as a programmer it's really tedious and too much of a work, we try to focus our energies on doing things smart way not the hard way. So we just write k = a+b+c * d. On writing k = a+b+c * d and we think which one gets executed first, some of you might reply that well according to PEMDAS c*d gets executed first right ? No, that's not true. 26 | 27 | On writing the expression k = a+b+c * d without parentheses we rely upon precedence and as we know higher precedence is multiplication then addition so compiler will not write the machine code which evaluates the expression in infix form only rather it will convert it into some post-fix form and then evaluate. For converting into post-fix form compiler needs fully parenthesised expression. So compiler will consider **k = a+b+c * d** as fully parenthesised based upon PEMDAS precedence rule i.e. compiler will parenthesise the expression. It can be visualised as following steps : 28 | Step 1 : **k = a+b+(c * d)** = Parentheses around multiplication first due to highest precedence 29 | Step 2 : **k = (a+b)+(c * d)** Due to associativity from left to right of operators as both are + operators. 30 | Step 3 : **k = ((a+b)+(c * d))** This is how compiler will treat the expression. Now it will evaluate addition first. So what's the use of precedence ? To apply parentheses. 31 | 32 | # Some other Examples : 33 | 34 | ## - Area of a Circle : 3.14 * r * r 35 | 36 | ## - Root of a Quadratic Equation : Root 1 = (-b + sqrt(b * b - 4* a * c))/2*a 37 | 38 | ## Root 2 = (-b - sqrt(b * b - 4* a * c))/2*a 39 | 40 | - ## Speed Formula, s = (v * v - u * u) /2*a 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /02. C++ Basics/07. expressions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | int main(int argc, const char **argv) 5 | { 6 | 7 | /* 8 | AREA OF A CIRCLE 9 | float r, area; 10 | cout << "Enter Radius : "; 11 | cin >> r; 12 | area = 3.1425f * r * r; 13 | // area = 22 / 7 * r * r; // Gives us int result as 22/7 forces entire thing to be int but inaccurate as it gives quotient of 22/7 14 | // area = 22 / 7.0 * r * r; // Leads to result being int but accurately rounded off to int. 15 | area = (float)22 / 7 * r * r; // Another way to do the same. 16 | cout << "Area of circle is : " << area << " units." << endl; 17 | 18 | */ 19 | /* 20 | ROOTS OF QUADRATIC EQUATION 21 | 22 | int a, b, c; 23 | float root_1, root_2; 24 | cout << "Enter 3 coefficients of quadratic equation i.e. a,b and c in that order : "; 25 | cin >> a >> b >> c; 26 | 27 | root_1 = (-b + sqrt(b * b - 4 * a * c)) / 2 * a; 28 | root_2 = (-b - sqrt(b * b - 4 * a * c)) / 2 * a; 29 | cout << "Root #1 of equation having coefficients a = " << a << ", b = " << b << ", c = " << c << "is : " << root_1 << endl; 30 | cout << "Root #2 of equation having coefficients a = " << a << ", b = " << b << ", c = " << c << "is : " << root_2 << endl; 31 | 32 | */ 33 | int u, v, a; 34 | float speed; 35 | 36 | cout << "Enter initial velocity (u) : "; 37 | cin >> u; 38 | 39 | cout << "Enter final velocity (v) : "; 40 | cin >> v; 41 | 42 | cout << "Enter acceleration (a) : "; 43 | cin >> a; 44 | 45 | speed = (v * v - u * u) / (2 * a); 46 | cout << "Speed is " << speed << endl; 47 | 48 | return 0; 49 | } -------------------------------------------------------------------------------- /02. C++ Basics/08. compound_operators.cpp: -------------------------------------------------------------------------------- 1 | // Compound Arithmetic Operator 2 | #include 3 | using namespace std; 4 | int main() 5 | { 6 | int sum = 10, x = 5; 7 | sum += x; 8 | cout << sum << endl; 9 | 10 | int fact = 10, y = 5; 11 | fact *= y; 12 | cout << fact << endl; 13 | return 0; 14 | } -------------------------------------------------------------------------------- /02. C++ Basics/09. pre_post_inc_dec_operators.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | /* 3 | There area totally 4 kinds of pre/post increment and decrement operators. 4 | 1. Pre Increment (++x) Unary operator, much faster than x = x+1 a binary operator. 5 | 2. Post Increment (x++) 6 | 3. Pre Decrement (--x) 7 | 4. Post Decrement (x--) 8 | */ 9 | using namespace std; 10 | int main(int argc, char const *argv[]) 11 | { 12 | int x = 5, storage; 13 | storage = ++x; // Value of x incremented first and then as 6 it is stored in storage var. 14 | 15 | cout << "PRE/POST INCREMENT" << endl; 16 | // ------------------------------------PRE/POST-INCREMENT BEGINS--------------------------------------------------- 17 | cout << endl; 18 | cout << "Example of PRE INCREMENT when x = 5 : " << endl; 19 | cout << endl; 20 | cout << "Value of x incremented first and then as 6 it is stored in storage var." << endl; 21 | cout << "So, X = " << x << " and Storage = " << storage << endl; 22 | cout << endl; 23 | cout << "Doing a post increment and storing it to storage var again and results are as follows : " << endl; 24 | storage = x++; // Value which was in previous stage i.e. 6 is stored in storage var and then incremented to 7. 25 | cout << "Value which was in previous stage i.e. 6 is stored in storage var and then incremented to 7." << endl; 26 | cout << "So we get 6 as value of storage when printed and value of x as 7 as it was inceremented after storing to storage." << endl; 27 | cout << "Storage = " << storage << " X = " << x << endl; 28 | // ------------------------------------PRE/POST-INCREMENT ENDS----------------------------------------------------- 29 | x = 5; 30 | cout << endl; 31 | 32 | cout << "PRE/POST DECREMENT" << endl; 33 | cout << endl; 34 | cout << "RESET X to 5" << endl; 35 | cout << endl; 36 | storage = --x; // Value of x decremented first and then as 4 it is stored in storage var. 37 | 38 | cout << "Value of x decremented first and then as 6 it is stored in storage var. So, X = " << x << " and Storage = " << storage << endl; 39 | 40 | storage = x--; // Value which was in previous stage i.e. 4 is stored in storage var and then decremented to 3. 41 | cout << "Value which was in previous stage i.e. 4 is stored in storage var and then decremented to 3." << endl; 42 | cout << "So we get 4 as value of storage when printed and value of x as 3 as it was inceremented after storing to storage." << endl; 43 | cout << "Storage = " << storage << endl; 44 | cout << "X = " << x << endl; 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /02. C++ Basics/10. bitwise_operators.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Bitwise operations occur on the bits of data and not on the entire data as single unit. 3 | 4 | Bit-Wise Operators which are available : 5 | 6 | & (bitwise AND) Takes two numbers as operands and does AND on every bit of two numbers. 7 | The result of AND is 1 only if both bits are 1. 8 | 9 | | (bitwise OR) Takes two numbers as operands and does OR on every bit of two numbers. 10 | The result of OR is 1 any of the two bits is 1. 11 | 12 | ^ (bitwise XOR) Takes two numbers as operands and does XOR on every bit of two numbers. 13 | The result of XOR is 1 if the two bits are different. 14 | 15 | << (left shift) Takes two numbers, left shifts the bits of the first operand, 16 | the second operand decides the number of places to shift. 17 | If a number x is left shift by i positions then result is x * 2^i.Sign bit is not affected and stays same. 18 | 19 | >> (right shift) Takes two numbers, right shifts the bits of the first operand, 20 | the second operand decides the number of places to shift. 21 | If a number x is right shift by i then x will get divided by 2^i. Sign bit is not affected and stays same. 22 | 23 | ~ (bitwise NOT) Takes one number and inverts all bits of it 24 | 25 | */ 26 | 27 | #include 28 | using namespace std; 29 | int main(int argc, const char **argv) 30 | { 31 | int x = 11, y = 5, z; 32 | cout << "X = " << x << "\tY = " << y << endl; 33 | z = x & y; 34 | cout << "Bit-Wise & (AND) on X & Y gives : " << z << endl; 35 | z = x | y; 36 | cout << "Bit-Wise | (OR) on X & Y gives : " << z << endl; 37 | z = x ^ y; 38 | cout << "Bit-Wise ^ (XOR) on X & Y gives : " << z << endl; 39 | cout << "Value of y i.e. 0000 0101 before left shift by 1 = " << y << endl; 40 | z = y << 1; 41 | cout << "Now we have shifted y by 1 to left i.e. previous value should increase by 2^1 i.e. 5 * 2." << endl; 42 | cout << "Value of y after 1 left shift is = " << z << endl; 43 | x = 20; 44 | cout << "Now value of x = " << x << endl; 45 | cout << "On doing right shift >> by 1 we would be dividing x i.e. 20 by 2^1 so expected answer is 20/2 = 10." << endl; 46 | z = x >> 1; 47 | cout << "Value of x after right shift 1 comes to be = " << z << endl; 48 | x = 5, y; 49 | y = ~x; 50 | cout<<"Not of ~5 = "< 2 | using namespace std; 3 | typedef int marks; 4 | enum dept 5 | { 6 | CSE = 1, 7 | ECM, 8 | ECE, 9 | CIVIL, 10 | MECH, 11 | EEE 12 | }; 13 | enum day 14 | { 15 | mon, 16 | tue, 17 | wed, 18 | thu, 19 | fri, 20 | sat, 21 | sun 22 | }; // Enum used to define our own data type 23 | int main(int argc, char const *argv[]) 24 | { 25 | day d; 26 | // d = 1; // Gives error 27 | d = mon; // This is correct to assign. 28 | cout << "Value of monday is : " << d << endl; 29 | cout << "Directly displaying tue or thu instead of using enum" << endl; 30 | cout << tue << " " << thu << endl; // Gives value as the index of tue and thu. 31 | // mon++; // This is wrong as expression of enum type can't be modified. 32 | 33 | /* 34 | It is like an identifier mon, tue...sat or sun. 35 | So, to variable d of type enum we can only assign values that we have mentioned above. 36 | All these are constants under the name of day and we can create a var of type day and use 37 | those constants for variables which starts from 0. 38 | */ 39 | enum day_2 40 | { 41 | Mon = 1, 42 | Tue, 43 | Wed, 44 | Thu, 45 | Fri, 46 | Sat, 47 | Sun 48 | }; 49 | day_2 var; // Variable of type day_2 50 | cout << endl; 51 | cout << "Number assigned to days if Mon = 1 is done is as follows : " << endl; 52 | cout << "Mon = " << Mon << endl; 53 | cout << "Tue = " << Tue << endl; 54 | cout << "Wed = " << Wed << endl; 55 | cout << "Thu = " << Thu << endl; 56 | cout << "Fri = " << Fri << endl; 57 | cout << "Sat = " << Sat << endl; 58 | cout << "Sun = " << Sun << endl; 59 | enum day_3 60 | { 61 | Mon_1 = 1, 62 | Tue_1, 63 | Wed_1, 64 | Thu_1 = 10, 65 | Fri_1, 66 | Sat_1, 67 | Sun_1 68 | }; 69 | cout << endl; 70 | cout << "Number assigned to days if Mon = 1 and Thu = 10 is as follows : " << endl; 71 | cout << "Mon_1 = " << Mon_1 << endl; 72 | cout << "Tue_1 = " << Tue_1 << endl; 73 | cout << "Wed_1 = " << Wed_1 << endl; 74 | cout << "Thu_1 = " << Thu_1 << endl; 75 | cout << "Fri_1 = " << Fri_1 << endl; 76 | cout << "Sat_1 = " << Sat_1 << endl; 77 | cout << "Sun_1 = " << Sun_1 << endl; 78 | 79 | marks m1, m2; 80 | m1 = 20; 81 | m2 = 35; 82 | cout << "Values assigned to m1 and m2 via typedef are : " << endl; 83 | cout << "m1 = " << m1 << endl; 84 | cout << "m2 = " << m2 << endl; 85 | return 0; 86 | } 87 | /* 88 | Enum is used to define a group of related constants under one name. 89 | Other ways to declare constants include : 90 | #define mon 0 91 | const int mon = 0; 92 | 93 | */ 94 | /*-----------------------TYPEDEF----------------------------------------- 95 | typedef used to define our own data type or giving alias to some other data type, so it is 96 | easier for us to keep track, prevent errors and make code more readable. 97 | Above example gives alias to data type int used as marks. 98 | Because we might not know what's the use of 2 int variables declared out of nowhere so it is better to have 99 | 2 int variables which are declared as marks m1,m2 to give us an idea these something to do with marks. 100 | 101 | 102 | */ -------------------------------------------------------------------------------- /02. C++ Basics/12. salary.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | typedef float salary; 11 | salary basic, per_allow, per_deduct, net; 12 | cout << "Enter Basic Salary : "; 13 | cin >> basic; 14 | cout << "Enter Percentage of Allowances : "; 15 | cin >> per_allow; 16 | cout << "Enter Percentage of Deductions : "; 17 | cin >> per_deduct; 18 | net = basic + basic * per_allow / 100 - basic * per_deduct / 100; 19 | cout << "Net Salary is : " << net << endl; 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /03. Conditional Statements/02. dynamic_declaration.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int a = 10, b = 5; 11 | /*if (true) 12 | { 13 | int c = a + b; 14 | cout << c << endl; 15 | } 16 | // cout << c; //Gives an error saying identifier is undefined. 17 | */ 18 | 19 | // When we do not need a variable throughout the program but only to check a condition 20 | 21 | /*We can either create an empty block and enclose the variable we want to limit in scope using {} - A Dummy Block 22 | 23 | */ 24 | 25 | if (int c = a + b; c > 10) // Available only in C++ 17. 26 | { 27 | cout << "Sum is greater than 10.\n"; 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | /* 34 | C++ allows declaration of variables as per our needs within a specified scope or throughout the program that's our choice. 35 | In C we were supposed to declare all the variables in the beginning of a program at one place. 36 | In above example based on some if condition we declare c and use it to print sum and outside the {} c variable won't exist. 37 | */ 38 | -------------------------------------------------------------------------------- /03. Conditional Statements/03. switch_case.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | // Program to take number of day of the week and print the day in alphabets 11 | int day; 12 | cout << "Enter the day number : "; 13 | cin >> day; 14 | switch (day) 15 | { 16 | case 1: 17 | cout << "Day is Monday." << endl; 18 | break; 19 | 20 | case 2: 21 | cout << "Day is Tuesday." << endl; 22 | break; 23 | 24 | case 3: 25 | cout << "Day is Wednesday." << endl; 26 | break; 27 | 28 | case 4: 29 | cout << "Day is Thursday." << endl; 30 | break; 31 | 32 | case 5: 33 | cout << "Day is Friday." << endl; 34 | break; 35 | 36 | case 6: 37 | cout << "Day is Saturday." << endl; 38 | break; 39 | 40 | case 7: 41 | cout << "Day is Sunday." << endl; 42 | break; 43 | 44 | default: 45 | cout << "Enter valid day number." << endl; 46 | break; 47 | } 48 | return 0; 49 | } 50 | 51 | /* 52 | Switch case is a branch and control statement. Construct of switch case looks like following : 53 | 54 | switch (expression) // NOTE : Expression can be int or char type variable. 55 | { 56 | case 1: 57 | code for case 1 58 | break; 59 | case 2: 60 | code for case 2 61 | break; 62 | default: 63 | code for default case (OPTIONAL), if break written anywhere other than last then use break. 64 | } 65 | 66 | SWITCH cases are used for menu-driven programs where user has choices to select from, for every case we write a code. 67 | We can have nested switch cases as well. 68 | */ -------------------------------------------------------------------------------- /03. Conditional Statements/04. switch_case_calculator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | cout << "MENU" << endl; 11 | cout << "1. Add \n" 12 | << "2. Subtract \n" 13 | << "3. Multiply \n" 14 | << "4. Divide \n"; 15 | int option; 16 | cin >> option; 17 | int a, b, c; 18 | cout << "Enter two numbers : "; 19 | cin >> a >> b; 20 | switch (option) 21 | { 22 | case 1: 23 | /* code */ 24 | c = a + b; 25 | cout << "Sum = " << c << endl; 26 | break; 27 | case 2: 28 | c = a - b; 29 | cout << "Difference = " << c << endl; 30 | break; 31 | case 3: 32 | c = a * b; 33 | cout << "Product = " << c << endl; 34 | break; 35 | case 4: 36 | c = a / b; 37 | cout << "Quotient = " << c << endl; 38 | break; 39 | 40 | default: 41 | cout << "Invalid Choice"; 42 | break; 43 | } 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /03. Conditional Statements/05. bill_discount_calculator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | */ 5 | #include 6 | using namespace std; 7 | int main() 8 | { 9 | int tot_amt; 10 | cout << "Enter the total amount : "; 11 | cin >> tot_amt; 12 | if (tot_amt < 0) 13 | { 14 | cout << "Don't drink and pay! Am I a joke to you ? -_-''''''"; 15 | exit(0); 16 | } 17 | else if (tot_amt > 0 && tot_amt < 100) 18 | { 19 | cout << "Sorry No Discount! Discounts are only applicable for orders above 100."; 20 | exit(0); 21 | } 22 | 23 | else if (tot_amt >= 100 && tot_amt <= 500) 24 | { 25 | float discount = 0.1 * tot_amt; 26 | cout << "Discount that you get is 10% which is : " << discount << endl; 27 | float final_amt = tot_amt - discount; 28 | cout << "Final amount that you have to pay is " << tot_amt << " - " << discount << " = " << final_amt << endl; 29 | cout << "Thanks for visiting. Visit again soon :) "; 30 | } 31 | else 32 | { 33 | float discount = 0.2 * tot_amt; 34 | cout << "Discount that you get is 20% which is : " << discount << endl; 35 | float final_amt = tot_amt - discount; 36 | cout << "Final amount that you have to pay is " << tot_amt << " - " << discount << " = " << final_amt << endl; 37 | cout << "Thanks for visiting. Visit again soon :) "; 38 | } 39 | 40 | return 0; 41 | } -------------------------------------------------------------------------------- /03. Conditional Statements/06. leap_year.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | /* 7 | edited by : Pruthviraj Jadhav 8 | email : k9730130467@gmail.com 9 | */ 10 | #include 11 | using namespace std; 12 | int main() 13 | { 14 | int year ; 15 | cout << "Enter the year you want to check for leap year : "; 16 | cin >> year; 17 | if (year % 4 == 0) 18 | { 19 | if (year % 100 == 0) 20 | { 21 | if (year % 400 == 0) 22 | cout << "Year " << year << " is leap year."; 23 | else 24 | cout << "Year " << year << " is not a leap year."; 25 | } 26 | else 27 | cout << "Year " << year << " is a leap year."; 28 | } 29 | else 30 | cout << "Year " << year << " is not a leap year."; 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /04. Loops/01. Loops.md: -------------------------------------------------------------------------------- 1 | # Loops 2 | 3 | Loops are iterative statements. As long as the condition is correct the code inside the block {} will continue to run. 4 | 5 | There are 4 types of loops in C++ : 6 | 7 | 1. While loop : 8 | 9 | ```c++ 10 | while (condition){ 11 | statements to be executes 12 | if the condition is true 13 | } 14 | ``` 15 | 16 | 2. do while loop : Ideal for case when you want program to run atleast once. 17 | 18 | ```c++ 19 | do{ 20 | set of conditions to be executed first (atleast once) 21 | } 22 | while(condition to check for){ 23 | repeats the stuff inside do 24 | if condition matches 25 | } 26 | ``` 27 | 28 | 3. for loop : Needs initialization, condition, updation parameters to work. First initializer is executed, then condition is checked , on matching body below is executed and then updation is done, then again condition is checked and then body is executed. 29 | 30 | ```c++ 31 | for(initialize, condition to check, update the initializer) 32 | { 33 | set of conditions to be executed 34 | } 35 | ``` 36 | 37 | 4. ```c++ 38 | for (type x : collection/array){ 39 | useful for accessing all the elements of an array. 40 | } 41 | ``` 42 | 43 | -------------------------------------------------------------------------------- /04. Loops/02. display_numbers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int i = 1; // Initialization for while loop 11 | // Using for loop 12 | /* 13 | for (int i = 1; i <= 10; i++) 14 | { 15 | cout << i << endl; 16 | } 17 | */ 18 | 19 | /* 20 | while (i <= 10) // Condition 21 | { 22 | cout << i << endl; 23 | i++; // Updation 24 | } 25 | */ 26 | 27 | do // do-while loop 28 | { 29 | cout << i << endl; 30 | i++; 31 | } while (i <= 10); 32 | 33 | /* 34 | for(;;) // Infinite loop 35 | { 36 | cout<10) // Setting a condition to break free from infinite for loop. 38 | break; 39 | } 40 | */ 41 | return 0; 42 | } 43 | /* 44 | If you have a number of loops to iterate then go for for loop, if you don't know then while or do-while loop. 45 | */ 46 | -------------------------------------------------------------------------------- /04. Loops/03. sum_n_natural_numbers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int n, sum = 0; 11 | cout << "Enter the number upto which you want to know the sum : "; 12 | cin >> n; 13 | for (int i = 1; i <= n; i++) 14 | { 15 | sum += i; 16 | } 17 | cout << "Sum is " << sum << endl; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /04. Loops/04. multiplication_table.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int n; 11 | cout << "Enter the number whose multiplication table you want to print : " << endl; 12 | cin >> n; 13 | for (int i = 1; i <= 10; i++) 14 | { 15 | /* code */ 16 | cout << n << " X " << i << " = " << n * i << endl; 17 | } 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /04. Loops/05. factorial.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int n, result = 1; 11 | cout << "Enter the number whose factorial you want to print : "; 12 | cin >> n; 13 | if (n < 0) 14 | { 15 | cout << "Factorial of negative numbers does not exist.\n"; 16 | } 17 | else if (n == 0 || n == 1) 18 | { 19 | cout << "Factorial is 1.\n"; 20 | } 21 | else 22 | { 23 | for (int i = n; i >= 1; i--) 24 | { 25 | /* code */ 26 | result *= i; 27 | } 28 | cout << "Factorial is : " << result << "." << endl; 29 | } 30 | 31 | return 0; 32 | } -------------------------------------------------------------------------------- /04. Loops/06. find_factors.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int n; 11 | cout << "Enter a number : "; 12 | cin >> n; 13 | for (int i = 1; i <= n / 2; i++) 14 | { 15 | if (n % i == 0) 16 | cout << i << " is a factorial of " << n << "." << endl; 17 | } 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /04. Loops/07. prime_number.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int n; 11 | cout << "Enter a number : "; 12 | cin >> n; 13 | int counter = 0; 14 | for (int i = 1; i <= n / 2; i++) 15 | { 16 | if (n % i == 0) 17 | counter++; 18 | } 19 | if (counter > 2) 20 | { 21 | cout << "Given number " << n << " is not a prime number."; 22 | } 23 | else 24 | { 25 | cout << "Given number " << n << " is a prime number." << endl; 26 | } 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /04. Loops/08. display_digits_of_a_number.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int n, rev = 0; 11 | cout << "Enter a number : "; 12 | cin >> n; 13 | 14 | while (n != 0) 15 | { 16 | int r; 17 | r = n % 10; 18 | rev = rev * 10 + r; 19 | n /= 10; 20 | } 21 | cout << "New number is : " << rev << endl; 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /04. Loops/09. sum_of_digits_of_a_number.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int n, sum = 0; 11 | cout << "Enter a number : "; 12 | cin >> n; 13 | while (n != 0) 14 | { 15 | int r; 16 | r = n % 10; 17 | sum += r; 18 | n /= 10; 19 | } 20 | cout << "Sum of digits of the number " << n << " is : " << sum << endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /04. Loops/10. gcd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int n, m; 11 | cout << "Enter 2 numbers : "; 12 | cin >> m >> n; 13 | 14 | while (m != n) 15 | { 16 | if (m > n) 17 | m -= n; 18 | else 19 | { 20 | n -= m; 21 | } 22 | } 23 | cout << "GCD : " << m << endl; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /04. Loops/11. palindrome.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int n, rev = 0; 11 | cout << "Enter a number : "; 12 | cin >> n; 13 | int n1 = n; 14 | while (n1 != 0) 15 | { 16 | int r; 17 | r = n1 % 10; 18 | rev = rev * 10 + r; 19 | n1 /= 10; 20 | } 21 | if (n == rev) 22 | cout << "Number " << n << " is a palindrome."; 23 | else 24 | { 25 | cout << "Number " << n << " is not a palindrome."; 26 | } 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /05. Arrays/01. Arrays.md: -------------------------------------------------------------------------------- 1 | # Arrays 2 | 3 | Arrays are useful for storing collection of similar data type together. Arrays are useful when we want to store set of values in our program, then we use array of data items. 4 | 5 | ```c++ 6 | int a[5]; // We are able to store 5 integers in continuous memory block 7 | ``` 8 | 9 | In arrays location can be accessed with the help of index. Arrays are zero indexed. 10 | 11 | ### Ways to create and Initialize array : 12 | 13 | ```c++ 14 | int a[5]; // Declaration of an array 15 | int b[5] = {1,2,3,5,8}; // Declaration with size and initialization 16 | int c[] = {1,5,8,6,7,136,65}; // Declaration without size with initialization 17 | int d[5] = {1,2} // Declaration with size but partial initialization 18 | int e[5] = {0}; // Declaration with partial initialization. All the values in the array becomes zero. 19 | ``` 20 | 21 | ## Different Types of Arrays : 22 | 23 | ## Int : 24 | 25 | ```c++ 26 | int a[5] = {1,65,98,456,132,68}; 27 | ``` 28 | 29 | ## Float : 30 | 31 | ```c++ 32 | float b[5] = {1.5,65.5,12.6,98.7,74.9}; 33 | ``` 34 | 35 | ## Char : 36 | 37 | ```c++ 38 | char arr[4] = {'a','g','e','k'}; 39 | ``` 40 | 41 | -------------------------------------------------------------------------------- /05. Arrays/02. array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int a[5] = {1, 3, 5, 7, 9}; 11 | cout << "Completely Initialized Int Array A : " << endl; 12 | for (int x : a) // For each loop very easy and important for Array data structure. Read as for x in array a. 13 | // For each loop iterates through elements of the array. Introduced in C++ 11. 14 | cout << x << endl; 15 | cout << endl; 16 | 17 | int b[6] = {1, 3, 5}; // Keeping the array incomplete to see what is the outcome result. 18 | cout << "Partial Initialized Int Array B : " << endl; 19 | for (int y : b) // Shows that for each loop will work according to size of array and not acc. to number of elements 20 | // initialized in the array. 21 | cout << y << endl; 22 | cout << endl; 23 | 24 | float c[6] = {1.2, 2.4, 3.6, 48.54, 99.48, 54.88}; 25 | cout << "Completely Initialized Float Array C : "; 26 | for (float z : c) 27 | cout << z << endl; 28 | cout << endl; 29 | 30 | float d[6] = {12.6, 82.4, 43.6, 4.54, 77.48, 84.88}; // No need to know the type of array. 31 | cout << "Completely Initialized Float Array D with auto : " << endl; 32 | for (auto z : d) 33 | cout << z << endl; 34 | cout << endl; 35 | 36 | char e[5] = {'A', 66, 'C', 68, 'E'}; // No need to know the type of array. 37 | cout << "Completely Initialized Char Array E with auto : " << endl; 38 | for (auto z : e) 39 | cout << z << endl; 40 | cout << endl; 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /05. Arrays/03. sum_of_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int array[5] = {10, 20, 30, 40, 50}; 11 | // -------------------------------------------------------------------------------------- 12 | /* 13 | // To find sum of elements in an array 14 | int sum = 0; 15 | for (auto x : array) 16 | sum += x; 17 | cout << "Sum is " << sum; 18 | */ 19 | // --------------------------------------------------------------------------------------- 20 | // --------------------------------------------------------------------------------------- 21 | // To find the minimum or maximum element in an array : 22 | /* 23 | int max = -32678; 24 | for (auto temp : array) 25 | { 26 | if (temp > max) // use if (temp < min) then min = temp with min = INT64_MAX initiall for minimum number in array 27 | { 28 | max = temp; 29 | } 30 | } 31 | cout << "Max element is : " << max; 32 | */ 33 | // --------------------------------------------------------------------------------------- 34 | // --------------------------------------------------------------------------------------- 35 | // To search for an element in an array : 36 | /* 37 | There are 2 methods of searching : 38 | 1. Linear Search 2. Binary Search (Requires sorted array) 39 | 40 | 1. Linear Search : Use a for loop for or for each loop to compare whether the current element is the one we are 41 | searching for. If not then we move to the next element, if it is the element then we say found at index #. 42 | 43 | 44 | */ 45 | // --------------------------------------------------------------------------------------- 46 | /* 47 | int user_input; 48 | cout << "Enter the number you want to search for in the array : "; 49 | cin >> user_input; 50 | int counter = 0; 51 | for (auto x : array) 52 | { 53 | 54 | if (x == user_input) 55 | { 56 | cout << "Number " << user_input << " is found at the location : " << counter; 57 | 58 | exit(0); 59 | } 60 | counter++; 61 | } 62 | cout << "Not found!"; 63 | 64 | */ 65 | 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /05. Arrays/04. nested_for_loop.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | for (int i = 1; i <= 5; i++) // For rows 11 | { 12 | for (int j = 1; j <= 5; j++) // Inner for loop for displaying a line, for columns inner loop 13 | { 14 | cout << "(" << i << "," << j << ") "; // Shows how i and j changes 15 | } 16 | cout << endl; // Outer for loop is to repeat the lines printed by inner loop 17 | } 18 | 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /05. Arrays/05. patterns.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | /* 11 | // For printing square pattern 12 | 13 | for (int i = 1; i <= 5; i++) 14 | { 15 | for (int j = 1; j <= 5; j++) 16 | { 17 | cout << "* "; 18 | } 19 | cout << endl; 20 | } 21 | */ 22 | /* 23 | for (int i = 1; i <= 5; i++) // Prints a stair format star pattern which goes from 1 to 5 star. 24 | { 25 | for (int j = 1; j <= i; j++) 26 | { 27 | cout << "* "; // Shows how i and j changes 28 | } 29 | cout << endl; // Outer for loop is to repeat the lines printed by inner loop 30 | } 31 | */ 32 | 33 | /* 34 | for (int i = 1; i <= 5; i++) // Prints a stair format star pattern which goes from 5 to 1 star . top-left stair 35 | { 36 | for (int j = 1; j <= 5 - i + 1; j++) 37 | { 38 | cout << "* "; // Shows how i and j changes 39 | } 40 | cout << endl; // Outer for loop is to repeat the lines printed by inner loop 41 | } 42 | */ 43 | for (int i = 1; i <= 5; i++) // Prints a stair format star pattern which goes from 1 to 5 star . bottom-right stair 44 | { 45 | { 46 | for (int j = 1; j <= 5; j++) 47 | { 48 | if (i + j > 5) // use if (i<=j) for top-right triangle which goes from 5 to 1 star. 49 | cout << "* "; 50 | else 51 | { 52 | cout << " "; 53 | } 54 | } 55 | cout << endl; 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /05. Arrays/06. matrix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int A[2][3] = {3, 3, 3, 3, 3, 3}; 11 | int B[2][3] = {1, 1, 1, 1, 1, 1}; 12 | int C[2][3]; 13 | for (int i = 0; i < 2; i++) 14 | { 15 | for (int j = 0; j < 3; j++) 16 | { 17 | C[i][j] = A[i][j] + B[i][j]; 18 | } 19 | } 20 | cout << endl; 21 | cout << "Sum of 2 matrices comes out to be : " << endl; 22 | for (int i = 0; i < 2; i++) 23 | { 24 | for (int j = 0; j < 3; j++) 25 | { 26 | cout << C[i][j] << " "; 27 | } 28 | cout << endl; 29 | } 30 | cout << endl; 31 | for (int i = 0; i < 2; i++) 32 | { 33 | for (int j = 0; j < 3; j++) 34 | { 35 | C[i][j] = A[i][j] - B[i][j]; 36 | } 37 | } 38 | cout << endl; 39 | cout << "Difference of 2 matrices comes out to be : " << endl; 40 | for (int i = 0; i < 2; i++) 41 | { 42 | for (int j = 0; j < 3; j++) 43 | { 44 | cout << C[i][j] << " "; 45 | } 46 | cout << endl; 47 | } 48 | cout << endl; 49 | /* 50 | for (int i = 1; i <= 5; i++) // For rows 51 | { 52 | for (int j = 1; j <= 5; j++) // Inner for loop for displaying a line, for columns inner loop 53 | { 54 | cout << "(" << i << "," << j << ") "; // Shows how i and j changes 55 | } 56 | cout << endl; // Outer for loop is to repeat the lines printed by inner loop 57 | } 58 | */ 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /05. Arrays/07. average_of_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | author : Anmol Tomer 4 | email : anmol3540@gmail.com 5 | 6 | */ 7 | #include 8 | using namespace std; 9 | int main() 10 | { 11 | int n, i; 12 | float num[100], sum = 0.0, average; 13 | cout << "Enter the number of elements : "; 14 | cin >> n; 15 | float d; 16 | for (i = 0; i < n; ++i) 17 | { 18 | cout << i + 1 << ". Enter Number : "; 19 | cin >> num[i]; 20 | sum += num[i]; 21 | } 22 | average = sum / n; 23 | cout << "Average is : " << average; 24 | return 0; 25 | } -------------------------------------------------------------------------------- /05. Arrays/08. mat_multiplication.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int a[10][10], b[10][10], mult[10][10], r1, c1, r2, c2, i, j, k; 11 | cout << "Enter rows and columns for first matrix : "; 12 | cin >> r1 >> c1; 13 | cout << "Enter rows and columns for second matrix : "; 14 | cin >> r2 >> c2; 15 | if (c1 != r2) 16 | { 17 | cout << "Two matrices can't be multiplied."; 18 | return 0; 19 | } 20 | // Storing elements for first matrix 21 | cout << endl 22 | << "Enter number of elements of matrix 1 : " << endl; 23 | for (i = 0; i < r1; ++i) 24 | { 25 | for (j = 0; j < c1; ++j) 26 | { 27 | cout << "Enter elements of matrix 1 : " << endl; 28 | cin >> a[i][j]; 29 | } 30 | } 31 | // Storing elements of matrix 2 32 | cout << endl 33 | << "Enter number of elements of matrix 2 : " << endl; 34 | for (i = 0; i < r2; ++i) 35 | { 36 | for (j = 0; j < c2; ++j) 37 | { 38 | cout << "Enter elements of matrix 2 : " << endl; 39 | cin >> b[i][j]; 40 | } 41 | } 42 | // Multiplying matrix a and b and storing in array mult. 43 | for (i = 0; i < r1; ++i) 44 | for (j = 0; j < c2; ++j) 45 | { 46 | mult[i][j] = 0; 47 | for (k = 0; k < c1; ++k) 48 | { 49 | mult[i][j] += a[i][k] * b[k][j]; 50 | } 51 | } 52 | // Displaying the multiplication of two matrix. 53 | cout << endl 54 | << "Output Matrix : " << endl; 55 | for (i = 0; i < r1; ++i) 56 | for (j = 0; j < c2; ++j) 57 | { 58 | cout << " " << mult[i][j]; 59 | if (j == c2 - 1) 60 | cout << endl; 61 | } 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /06. Pointers/02. pointer_sample.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int a = 10; // A data variable 11 | int *ptr = &a; // Address variable declared with * and initialized with address of a. 12 | 13 | cout << "Printing a gives : " << a << endl; 14 | cout << "Printing Address of a using &a gives : " << &a << endl; 15 | cout << "Printing ptr gives us again address of a as *ptr = &a : " << ptr << endl; 16 | cout << "Printing &ptr gives us address of pointer i.e. : " << &ptr << endl; 17 | cout << "Printing *ptr gives us data stored at the address of a i.e. : " << *ptr << endl; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /06. Pointers/03. heap_memory.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int A[5] = {1, 2, 3, 4, 5}; // Created inside the stack when array is declared like this. 11 | cout << "Elements of array A stored in stack section are : "; 12 | for (auto x : A) 13 | cout << x << "\t"; 14 | cout << endl; 15 | 16 | cout << "The data stored in 2nd index at stack location is : " << A[2] << endl; 17 | // We can access the array in the stack section using index. Check below for accessing array in heap section. 18 | 19 | // Below is the code to create the array in heap. 20 | int *p; // Pointer p is created inside the stack. 21 | p = new int[5]; // new means memory is allocated from heap, we get array in heap. 22 | p[2] = 420; // Assigns 15 to second index memory location in heap section. 23 | cout << endl; 24 | cout << "The data stored in 2nd index at heap location is : " << p[2] << endl; 25 | // p = NULL; // If beforehand we assign p = NULL before deleting then we will lose track of the address which was 26 | // assigned to array created by p and it will be there in memory even if we do not want the array as long as the 27 | // program is running. 28 | delete[] p; 29 | p = NULL; 30 | // After delete we can do p = NULL meaning pointer p is not pointing anywhere and this is correct way to do it. 31 | 32 | /* Whenever we take a pointer and say new then the array is created in heap. 33 | The address of this array is stored inside the p. 34 | All the variables get memory in stack and only the ones which uses the word new and are accessed via pointers 35 | are stored in the heap. 36 | */ 37 | /*Code for writing the same thing above of array in a heap in a single program using syntax below : 38 | int *p = new int[5]; 39 | */ 40 | 41 | return 0; 42 | } 43 | 44 | /* 45 | Heap memory access using pointers. Heap memory is accessed dynamically, means the memory is 46 | allocated dynamically. Size of memory required in the heap is decided during the runtime and 47 | not at compile time. Here we see the difference when the memory is allocated during stack 48 | and when it is allocated to heap. 49 | 50 | The variables stored in stack get deleted automatically when code goes out of scope but the memory won't be delted 51 | just like that in heap i.e. it will be there as long as the program is running, so if we do not want heap memory 52 | in any case to last throughout the program and we need heap memory for a limited time then what we can do is 53 | deallocate the heap memory which can be done using delete []p; where [] is a symbol of array associated with p. 54 | 55 | MEMORY LEAK : Say apart from main function we allocated a memory and function has stopped, taken some memory in heap 56 | we have set pointer to the array in heap as NULL before deallocating this memory then memory belongs to the program 57 | but program is not pointing to it as the only way to access it has been assigned NULL that is the address of that 58 | array in heap has been forgotten so we can't deallocate it neither can we use/access it in our program, it just sits 59 | there taking up space. 60 | See for more reference : https://i.imgur.com/rPvjdrs.png 61 | 62 | 63 | */ -------------------------------------------------------------------------------- /06. Pointers/04. dynamic_mem_allocation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | /* 11 | int *ptr = new int[5]; //Create a pointer and assign a new array of size 5 in heap. 12 | ptr[0] = 12; //Storing the elements 13 | ptr[1] = 19; 14 | cout << ptr[1] << endl; // Accessing the elements 15 | 16 | // First we delete de-allocate the memory and then do nullptr to stop ptr pointing to that memory location 17 | delete[] ptr; 18 | ptr = nullptr; // nullptr a built-in literal made only for pointer for newer version of C++. 19 | */ 20 | 21 | // Benefit of having array in heap instead of stack section 22 | 23 | /* 24 | When we declare array of a fixed size in the program say 10 then there is no procedure 25 | in C++ for array to change its size in the middle of execution. What if user wants to enter 26 | more than 10 elements. 27 | So, we want to create an array depending upon the number of elements user will store into the array. 28 | We take size from the user, and we can create array[size]; this is an approach to this. 29 | This is possible as C++ allows dynamic declaration of array. 30 | After making the array once if we take another size from user and do array[size] once again 31 | it won't work as once the array is created in program it cannot be modified. 32 | 33 | To create a dynamic array inside the heap we take the number of elements and use pointer. 34 | */ 35 | /* 36 | // Creating array in heap the hard way 37 | int size; 38 | cout << "Enter the size of the array you want to create : "; 39 | cin >> size; 40 | int *p = new int[size]; // Take a pointer and create an array of size given by user. 41 | p[0] = 23; 42 | cout << "Element at 0 index in first array is : " << p[0] << endl; 43 | cout << "Enter new size : "; 44 | cin >> size; // Take size again 45 | p = new int[size]; 46 | p[2] = 49; 47 | cout << "Element at 2nd index in new array is : " << p[2] << endl; 48 | 49 | */ 50 | 51 | /**/ 52 | // Creating array in heap the easy way 53 | int *p = new int[20]; // Array created with size 20. p[i] can be 0 to 19 here 54 | // Later on in the program if we want array of larger size say 40 we can create that too. 55 | // Size 40 array will be created in heap and same ptr p will be pointing towards that array. 56 | // Before creating the array of larger size we de-allocate the memory which p currently holds of int[20] 57 | delete[] p; // and now we can create an array of larger size, to avoid memory leak. 58 | p = new int[40]; // p[i] can be 0 to 39 here. So, with same pointer we created a larger size array. 59 | // Here we created array of smaller size and then using the same pointer created an array of larger size. 60 | // More on heap memory and pointers later on. 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /06. Pointers/05. Pointer Arithmetic.md: -------------------------------------------------------------------------------- 1 | # Pointer Arithmetic 2 | 3 | Say we have an array 4 | 5 | ```c++ 6 | int A[5] = {2,4,6,8,10} ; // Some elements in an array 7 | int *p = A ; //Pointing the pointer to the array A 8 | ``` 9 | 10 | Much like the image below 11 | 12 | ![Image of Array and pointer p to it](https://i.imgur.com/lEOQnUW.png) 13 | 14 | Now, we can access the array by name or with the help of pointers. 15 | There are 5 pointer arithmetic operations : 16 | 17 | 1. **p++** : Pointer will move to the next location. That is it will move to the immediate next address. If in image above p points to address 200 and we assume each int is of 2 bytes then it will move to 202 on doing p++. It solely depends on the datatype of a pointer. A float pointer will move by 4 bytes, char pointer moves by 1 byte and so on. 18 | 2. **p--** : Pointer will move to the previous location. That is it will note move to the immediate previous address of 205 if we do p-- on 206. If in image above p points to address 206 and we assume each int is of 2 bytes then it will move to 204 on doing p--. It solely depends on the datatype of a pointer. A float pointer will move by 4 bytes, char pointer moves by 1 byte and so on. 19 | 3. **p += 2** : Adding any constant value to pointer is also allowed and will move the pointer to constant location places forward. Pointer will move to the next location as per the constant added. That is it will move to the next immediate address. If in image above p points to address 202 and we assume each int is of 2 bytes then it will move to 206 on doing p += 2. It solely depends on the datatype of a pointer. A float pointer will move by 4 bytes, char pointer moves by 1 byte and so on. 20 | 4. **p -= 2** : Subtracting any constant value to pointer is also allowed and will move the pointer to constant location places backward. Pointer will move to the previous location as per the constant subtracted. That is it will move to the previous immediate address. If in image above p points to address 202 and we assume each int is of 2 bytes then it will move to 206 on doing p += 2. It solely depends on the datatype of a pointer. A float pointer will move by 4 bytes, char pointer moves by 1 byte and so on. 21 | 5. **d = q - p** : When both p and q are pointers then addresses of p and q can be subtracted showing how far they are from each other. As depicted in the image below 22 | ![Distance between 2 pointers](https://i.imgur.com/9bMNxT5.png) 23 | 24 | Here p is at 200 and q is at 206 and each int is assumed to be of 2 bytes so this means **q-p/2** gives us 3. That means q is 3 locations ahead in the array of the pointer p. So, the formula to find out how far apart 2 pointers are pointer 1 address from pointer 2 address subtracted and entire thing divided by the size of data type the pointers are. 25 | 26 | (200-206)/3 means pointer 1 is nearer and pointer 2 is farther away as the answer comes out to be -3 on solving. If we get positive result that means first pointer is farther as compared to second pointer. Getting negative result means second pointer is far away. 27 | 28 | Only 5 arithmetic operations are allowed in pointers. Nothing else. 29 | 30 | -------------------------------------------------------------------------------- /06. Pointers/06. pointer_arithmetic.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int A[5]{2, 4, 6, 8, 10}; //Declare an array of size 5 and to it assign some values. 11 | cout << "Array A :\t"; 12 | for (auto x : A) 13 | cout << x << "\t"; 14 | cout << endl; 15 | 16 | int *p = A; // Take a pointers and make it point to array above. 17 | int *q = &A[4]; 18 | cout << "Places p and q are far from each other are : " << q - p << endl; 19 | // q - p gives us positive result which basically means that q is far away and we subtracted pointer closer or which comes first from it. 20 | // If we do p-q then we would get -4 which would mean that second pointer is far away and we subtracted closer pointer minus pointer far away. 21 | 22 | /* 23 | cout << "Pointer p on printing p gives : " << p << endl; 24 | cout << "Address of A is : " << &A << endl; 25 | 26 | cout << "Output of *p would be first location of the array i.e. :" << *p << endl; 27 | 28 | p++; 29 | cout << "Address in pointer p after incrementing using p++ is : " << p << endl; 30 | cout << "Output after incrementing pointer by using p++ is next element in Array i.e. : " << *p << endl; 31 | 32 | p--; // Using pointer arithmetic so we do not have to use dereference operator. 33 | cout << "Address in pointer p after decrementing using p-- is : " << p << endl; 34 | cout << "Output after decrementing pointer by using p-- is previous element in Array i.e. : " << *p << endl; 35 | 36 | cout << "Some more pointer arithmetic, increment by 2 and so on ..."; 37 | cout << "Output at p is : " << *p << endl; 38 | cout << "Output on incrementing by 2 p += 2 is element after 2 locations :" << *(p + 2) << endl; 39 | */ 40 | 41 | // Displaying all the elements of the array 42 | cout 43 | << "Address of p before the loop starts " << p << endl; 44 | for (int i = 0; i < 5; i++) 45 | { 46 | // cout << A[i] << endl; // Displays all the elements in the array. 47 | // cout << i[A] << endl; 48 | // cout << *(A + i) << endl; // * gives the data 49 | // cout << (A + i) << endl; // without * we get the addresses in memory using array name. 50 | // cout << (p + i) << endl; // without * we get the addresses in memory using pointer to array name. 51 | // cout << *(p + i) << endl; // * gives the data but we use dereference and using pointer name directly. 52 | // Instead of using array name in place of array name we can use pointer name indexing too. 53 | // cout << p[i] << endl; // As A and p both have the same memory address and they fetch memory_address[index] 54 | /*cout << *p << endl; // Using loop and increment the pointer position 55 | p++; */ 56 | 57 | // Another pointer arithmetic operation, here we take p pointing on A and another pointer q which points on A[4] 58 | // Here we find the difference between 2 pointers using q-p 59 | } 60 | cout << "Address of p after the loop ends " << p << endl; 61 | cout << "This shows that pointer changes its position during the loop."; 62 | 63 | return 0; 64 | } 65 | -------------------------------------------------------------------------------- /06. Pointers/08. Reference.md: -------------------------------------------------------------------------------- 1 | # **Reference** 2 | 3 | Reference is one of the powerful features of C++ and is exclusive to C++. If in main function we have a variable x and this x has some value and for this x there is some memory allocated say address 200/201. 4 | 5 | So what is reference ? If we declare another variable of same data type as x called y (suppose) . If we write int y then memory is allocated to it like an int maybe memory location 202/203. But if we write ```int &y``` this is a reference. 6 | 7 | So whenever we declare a reference we must initialize then and there only. 8 | 9 | ```c++ 10 | int x = 10 ; // At memory 200/201 11 | int &y = x ; // Reference with declaration and initialization. 12 | ``` 13 | 14 | **So what is this reference ?** 15 | 16 | Reference is nothing but a nickname of this variable, alias. So now x can be accessed using the name y too. So this leads to memory 200/201 which we were initially calling as x can now be called y as well. We do not need this in same function. In next article we will see how it is used. Same location can now be called with name x as well as y. 17 | 18 | If we do x++ then value become 11. Then if we say y++ then value becomes 12. As both x and y are accessing the same memory. 19 | 20 | ```c++ 21 | x++ ; // 10 becomes 11 22 | y++ ; // 11 becomes 12 23 | cout << x ; // Prints 12 24 | cout << y ; // Prints 12 25 | ``` 26 | 27 | It is not required inside the same function we are just learning what reference is. 28 | 29 | Now notice the following code snippet with variable a introduced 30 | 31 | ```c++ 32 | int a ; 33 | a = x; 34 | x = 25 ; 35 | ``` 36 | 37 | Let's see what is the difference between the two statements. We see that both the 2 statements involves x. On one side we have x on RHS of assignment while the second statement has x on LHS. 38 | 39 | Where x is on right we call it r-value and when x is on left we call it l-value. In r-value whatever data is there stored in memory address of x gets stored in a. Currently x has 12 so 12 will be stored in a. When we write x it means the value of variable x. Value is stored in the memory address of a like a literal a constant value. R-value is a data, constant value. 40 | 41 | In l-value when we say x = 25 then it means that 25 is to be stored in memory location of x, overwriting or erasing what was there in x earlier. In x = 25, x tells location where to write 25. 42 | 43 | When x is at RHS data of x is stored in the memory location of variable at left. In LHS X tells the address where value on right needs to be stored. 44 | 45 | In case of ```int &y = x``` , x is written on RHS and RHS means data. What is given in the name of y, the same address is given for y also, this means x here is l-value. 46 | 47 | Reference doesn't consume any memory. Once we declare and initialize a reference we cannot make it a nickname for another variable. Reference is internal pointer. -------------------------------------------------------------------------------- /06. Pointers/09. reference.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int x = 10; 11 | int &y = x; // y is a reference to x 12 | cout << "Value of x : " << x << endl; //Display value of X 13 | y++; // Increments value of x 14 | x++; // Again value of x incremented. 15 | cout << x << endl; // Same value of x incremented twice and we get answer as 12 16 | cout << "Address of X : " << &x << " Address of y : " << &y << endl; 17 | // We see that address of x and y are same. So y is not another variable but just another name with same address of x. 18 | // Declaration of any reference variable requires an initializer or a variable already declared whose memory it 19 | // will store. 20 | /*y = b; or &y = b; cannot be done as this is wrong because once initialized reference variable can't be assigned to another variable.*/ 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /06. Pointers/10. pointer_to_function.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | void display() 9 | { 10 | cout << "Hello"; 11 | } 12 | int max(int x, int y) 13 | { 14 | return x > y ? x : y; // Function to return max -> Checks if x>y ? if true then return x : else return y. 15 | } 16 | int min(int x, int y) 17 | { 18 | return x > y ? y : x; // Function to return min -> Checks if x>y ? if true then return y : else return x. 19 | } 20 | int main() 21 | { 22 | /* 23 | void (*fp)(); // Method of declaring a pointer to the function. Ptr to a function must be inside brackets() 24 | fp = display; // Assigning a name of a function to function pointer fp. The address of function will be stored here. 25 | (*fp)(); // Function call to the function display. 26 | */ 27 | int (*fp)(int, int); // Declare a function pointer to max or min as prototype same for both functions. 28 | fp = max; // Assign fp to max function. 29 | (*fp)(29, 21); // Expected return 29 as called on max. 30 | max(29, 21); 31 | fp = min; 32 | (*fp)(29, 21); // Expected return 21 as called on min now. 33 | return 0; 34 | } 35 | /* 36 | We know that we can have pointer to any primitive data type, we can also have pointer of type class. 37 | We can also have pointer to a function. Above we have display function not returning anything and having no parameters. 38 | If we want to call the function from main we can say display() and hello will be displayed. 39 | Now, instead of directly calling the function using a name we can also use a pointer to the function. 40 | We define a function to the pointer and we call it fp above. return_type(*function_pointer_name)(parameters) 41 | 42 | On declaring a pointer to a function everything is same as prototype of a function, but instead of function name we have 43 | pointer name in bracket with parameters in another bracket. 44 | Initialization done using function name. 45 | Calling done by giving function pointer name inside () and pass required parameters if any. 46 | 47 | Where we call the same pointer on max and min function we see that this is somewhat like polymorphism, different 48 | functions are called as pointer points towards different functions. So, this is same name but different functions. 49 | 50 | This is like polymorphism. In function over-riding internally functional pointers are used to achieve run-time polymorphism 51 | using function over-riding. One function pointer can point to any function with same signature/prototype. 52 | */ -------------------------------------------------------------------------------- /07. Functions/02. max_of_3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int max(int a, int b, int c) 9 | { 10 | if (a > b && a > c) 11 | return a; 12 | else if (b > c) 13 | return b; 14 | else 15 | return c; 16 | } 17 | 18 | int main() 19 | { 20 | cout << "Enter 3 integers to compare : "; 21 | int x, y, z, result; 22 | cin >> x >> y >> z; 23 | result = max(x, y, z); 24 | cout << "Maximum of 3 integers is : " << result; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /07. Functions/03. function_overloading.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int add(int x, int y) 9 | { 10 | return x + y; 11 | } 12 | /* Same name can be used as parameters being passed to this or signature of 2 functions are different though name is same 13 | Here though name is same but the numer of parameters taken by this add function below is 3 and this makes it different 14 | from a function which has same name add but takes in only 2 integers. 15 | C++ compiler can differentiate between 2 functions of same names based on parameters type and # of parameters being passed. 16 | This is called function overloading. Benefit here is that if # or type of parameters is different then 17 | we don't need to think of new names as the function is same only parameters type or # is different. 18 | 19 | */ 20 | int add(int x, int y, int z) 21 | { 22 | return x + y + z; 23 | } 24 | float add(float x, float y) 25 | { 26 | return x + y; 27 | } 28 | // So we can say that 2 functions with same name and same # of parameters can be different too if data type is different. 29 | int main() 30 | { 31 | int a = 10, b = 5, c, d; 32 | c = add(a, b); // We want to have a function which gives sum of 2 integers and store it in c. 33 | cout << "Output of add(a,b) with 2 parameters is : " << c; 34 | // Now we want to have another function which takes in 3 integers and sum is returned which is stored in d. 35 | d = add(a, b, c); 36 | cout << "Output of add(a,b,c) with 3 parameters is : " << d; 37 | // In C language we cannot have more than one function with same name but here we can have so. 38 | float i = 2.5, j = 7.5, k; 39 | k = add(i, j); 40 | cout << "Output of add(a,b) with 2 float parameters is : " << k; 41 | return 0; 42 | } 43 | 44 | /* 45 | FUNCTION OVERLOADING : Writing more than one function with the same name but different parameters. 46 | 47 | There would be name conflict in the case when return type is different but name of function along with parameters type 48 | and # of parameters are different. Much like example below : 49 | Example of name conflict : 50 | int max(int,int) 51 | float max(int,int) 52 | */ -------------------------------------------------------------------------------- /07. Functions/04. function_template.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | /* 9 | // Doing things overloaded way. 10 | int max(int x, int y) 11 | { 12 | return x > y ? x : y; // If x > y ? return x : else return y 13 | } 14 | float max(float x, float y) 15 | { 16 | return x > y ? x : y; 17 | } 18 | */ 19 | // ----------------------------------------------------------------------------------------------- 20 | // Function template way of doing things. 21 | template 22 | // T Max(T x, T y) 23 | T max(T x, T y) 24 | { 25 | return x > y ? x : y; 26 | } 27 | int main() 28 | { 29 | 30 | // cout << max(12.6, 56.5) << endl; / /This would give you error. 31 | // Check answer by Francois Andrieux on this link to use :: 32 | // cout << Max(12.6, 56.5) << endl;// This works too to have capital function name with namespace std. 33 | cout << "Output for float gives us : " << ::max(12.6, 56.5) << endl; 34 | cout << "Output for int gives us : " << ::max(112, 93) << endl; 35 | 36 | return 0; 37 | } 38 | 39 | /* 40 | FUNCTION TEMPLATE : The functions which are generic are function templates. Generalised in terms of data type. 41 | Above we see 2 examples to understand generic functions. 2 functions are just overloaded with 42 | different data type that's all. Number of parameters are same as well but datatype of parameters are different. 43 | From main if we call int c as above first function is called and float b calls the second function. 44 | 45 | If we notice the body of the function i.e. code/logic written is exactly same only datatype is different. 46 | So question arises... Why to write same function twice when there is only a difference in data type ? 47 | Or go into the hassle of function overloading ? Can't we just write a single function combining these 2 functions 48 | for any data type ? Yes we can. We do T for template in the above . 49 | 50 | We define template Which is a definition of T defined as class of type template. 51 | T is a template class and function is template function. Now when in the main function when via int c we call 52 | the function max then automatically T will be replaced by int and when we call via float b then T becomes float. 53 | Same function can be used with multiple data types as if it is a single function with difference of data types. 54 | Function template will not only work just for datatypes but also for objects of your classes. 55 | 56 | */ -------------------------------------------------------------------------------- /07. Functions/05. default_arguments.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | /* 9 | // The hard way to addition by function overloading 10 | int add(int x, int y) 11 | { 12 | return x + y; 13 | } 14 | // Overloaded functions with different number of arguments. 15 | int add(int x, int y, int z) 16 | { 17 | return x + y + z; 18 | } 19 | */ 20 | 21 | // Easy way via default argument passing 22 | int add(int x, int y, int z = 0) // Here we set var we are unsure of user would give or not as 0 by default 23 | { 24 | return x + y + z; // Assigned default value gets changed if user ever enters 3 parameters. 25 | } 26 | 27 | int max(int a, int b, int c = 0) 28 | { 29 | return a > b && a > c ? a : (b > c ? b : c); // Says if a>b and a>c ? return a : else check (b>c ? return b : else return c) 30 | } 31 | 32 | int main() 33 | { 34 | /* 35 | int c = add(2, 5); // Calls first function 36 | c = add(2, 5, 8); // Almost same, just adds one more integer. 37 | // What if we did 38 | c = add(2, 5, 0); // Same as function 1 right ? Yes, will call and give result same as function 1 39 | */ 40 | cout << "Sum with 2 parameters and third being default arg. = 0 is :" << add(2, 836) << endl; 41 | cout << "Sum with 3 parameters is : " << add(25, 66, 96) << endl; 42 | cout << "Max of 3 integers is " << max(26, 13, 56) << endl; 43 | cout << "Max with 2 integers and third being by default 0 is " << max(10, 20) << endl; 44 | return 0; 45 | } 46 | 47 | /* 48 | Here we learn about default arguments. Above are 2 functions with number of parameters being different. 49 | 50 | If we are ready to pass the third argument as zero then we do not need 1st function. 51 | Can we combine 2 functions into 1 ? Yeah use default argument. 52 | Using default argument we can eliminate function overloading for cases where datatype remains same but new function of 53 | same name is being written with only difference that being of number of parameters being passed. Instead set the parameters 54 | which you are unsure of use would pass or not as default inside the function. 55 | Try making the last parameters as default and not the first ones as most probably those would be supplied by user, 56 | the first arguments. 57 | 58 | Default argument can greatly replace what function overloading does for the case where everything stays same between 59 | 2 functions except the number of parameters of same datatype. 60 | */ -------------------------------------------------------------------------------- /07. Functions/06. pass_by_value.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | void swap(int a, int b) 9 | { 10 | int temp; 11 | temp = a; 12 | a = b; 13 | b = temp; 14 | cout << "Output of formal parameters a and b after swap(a,b) : " << a << " " << b << endl; 15 | } 16 | 17 | int main() 18 | { 19 | int x = 10, y = 20; 20 | cout << "Value of actual parameters x and y before swap(x,y) : " << x << " " << y << endl; 21 | swap(x, y); 22 | cout << "Output of actual parameters after swap(x,y) : " << x << " " << y << endl; // LOL swap doesn't happens. 23 | return 0; 24 | } 25 | /* 26 | C++ allows passing or call by using 3 different methods 27 | 28 | 1. Call by value or Pass by value 29 | 2. Call by address 30 | 3. Call by reference 31 | 32 | Call by value stores the values into the as the variables values' in activation record of function in stack memory. 33 | Inside swap functions' activation record a becomes 20 from 10 and b becomes 10 from 20. Function ends. 34 | As we know when function ends its memory inside the block gets deleted and due to this control comes to main function. 35 | Now we see indeed x and y didn't get swapped and 10, 20 is printed. 36 | So we learnt that in call by value values of variables being passed is copied in as values of variables in function. 37 | Formal parameters are the parameters of the function we define and what we supply are actual parameters inside main. 38 | So any changes done to formal parameters value does not change value of their actual parameters counterpart. Thus, formal 39 | parameters cannot modify the value of actual parameters. 40 | Call by value is ideally used if you want a function just to take values from n parameters and give an individual result R 41 | after some calculation. To return individual result you use call by value, by supplying values of actual parameters and 42 | getting result in return. 43 | REMEMBER : Changes are done in activation record of formal parameters and do not affect activation record of actual 44 | parameters. 45 | */ -------------------------------------------------------------------------------- /07. Functions/07. pass_by_address.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | void swap(int *a, int *b) 9 | { 10 | int temp; 11 | temp = *a; // Data of x is stored in a temp variable. 12 | *a = *b; // Data of y is now stored in data of x 13 | *b = temp; // Data of x now being stored into y which was stored in temp in step 1. 14 | cout << "Addresses of formal parameters a and b after swap(a,b) :\na = " << a << "\tb = " << b << endl; 15 | cout << "Values of formal parameters a and b after swap(a,b) :\na = " << *a << "\tb = " << *b << endl; 16 | } 17 | 18 | int main() 19 | { 20 | int x = 10, y = 20; 21 | cout << "Value of actual parameters x and y before swap(x,y) :\nx = " << x << "\ty = " << y << endl; 22 | cout << "Address of actual parameters x and y before swap(x,y) :\nx = " << &x << "\ty = " << &y << endl; 23 | swap(&x, &y); 24 | cout << "Output of actual parameters after swap(x,y) :\nx = " << x << "\ty = " << y << endl; // Aww yeah! Swap happens. 25 | cout << "Address of actual parameters x and y after swap(x,y) :\nx = " << &x << "\ty = " << &y << endl; 26 | return 0; 27 | } 28 | 29 | /* 30 | Here we have same code as 06. # but with some changes. 31 | In the function here we do not send the variable x and y to swap rather we send the address of x and y to swap. 32 | As we know that the address as value can only be stored by pointers so we make formal parameters as pointers in function 33 | definition above. 34 | 35 | This makes formal parameters as pointers to store address values and actual parameters passing their addresses to function. 36 | a is a pointers to x and b is a pointer to y. We won't be swapping the addresses but rather we swap the data inside 37 | the function definition above main. 38 | a has address of x and b has address of y. 39 | *a means data of x. We do the swapping and due to formal parameters being pointers we swap or modify the actual parameters 40 | and finally swapping happens properly. 41 | One function cannot access the variables of other functions that is precisely the reason why we do so using pointers. 42 | Pointer gives power to a function to access the parameters of the calling function. 43 | Swap function changes the values of x and y and swapping occurs. 44 | If we want to modify the actual parameters then we should go for call by address mechanism. 45 | 46 | */ -------------------------------------------------------------------------------- /07. Functions/08. pass_by_reference.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | void swap(int &a, int &b) 9 | { 10 | int temp; 11 | temp = a; 12 | a = b; 13 | b = temp; 14 | } 15 | 16 | int main() 17 | { 18 | int x = 10, y = 20; 19 | cout << "Value of actual parameters x and y before swap(x,y) :\nx = " << x << "\ty = " << y << endl; 20 | cout << "Address of actual parameters x and y before swap(x,y) :\nx = " << &x << "\ty = " << &y << endl; 21 | swap(x, y); 22 | cout << "Output of actual parameters after swap(x,y) :\nx = " << x << "\ty = " << y << endl; // Aww yeah! Swap happens. 23 | cout << "Address of actual parameters x and y after swap(x,y) :\nx = " << &x << "\ty = " << &y << endl; 24 | return 0; 25 | } 26 | 27 | /* 28 | References are nickname to a variable and has to be initialized at the declaration time and can't be null. 29 | 30 | We do very minor changes to the code and it is almost same as if it was call by value code. 31 | We do not make any changes where we call the function inside main. 32 | Instead in the function definition we take in int &a i.e. reference variables instead of int variables. 33 | 34 | Syntax is same as call by value only at the definition of the function we use & ampersand. 35 | In call by reference changes can be done to actual parameters. 36 | 37 | Due to & being used i.e. reference variables being taken in function definition when we pass x and y inside main 38 | to the function new activation record is not created instead x and y are also identified by the name a and b at memory 39 | &x and &y. 40 | 41 | When we use call by reference what happens at machine code generation phase is that where we call swap function 42 | inside the main there machine code of swap function will be copied. Machine code of function will be copied 43 | inside the main function at the place of function call. It becomes part of main function and as a result during 44 | call by reference even if it seems another function directly modifying main function in reality before that happens 45 | another function becomes a part of main function. 46 | Temp is also created in the activation record of the main function itself and will be there as long as the swap 47 | funcion code is being executed. 48 | 49 | Use call by reference when you want actual parameters to be modified. 50 | Loops inside call by references can lead to warnings as perfect copying of code by compiler might not happen. 51 | Using call by reference makes the function being called as in-line function. 52 | */ -------------------------------------------------------------------------------- /07. Functions/09. return_by_address.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int *fun(int size) 9 | { 10 | int *p = new int[size]; 11 | for (int i = 0; i < size; i++) 12 | p[i] = i + 1; 13 | return p; 14 | } 15 | int main() 16 | { 17 | int *ptr = fun(5); // Creates an array of size 5 in heap, initializes the elements and returns the pointer. 18 | // ptr will point to 0th index element of array in heap memory. 19 | 20 | return 0; 21 | } 22 | /* 23 | Return by Address kind of functions : Functions can also return addresses. Functions can take adderesses as parameters 24 | and in that case functions are called call by address kind of functions. 25 | 26 | Above we have a function named fun which returns size as a parameter. The function takes a pointer and creates an array 27 | of that size. As new is used then memory is created in the heap. When new is used memory is used inside the heap. 28 | Code creates an array in heap and p is pointer to that array. 29 | Then we have code to assign every index location a value more than its index. 0 will be 1. 1 will be 2 and nth index will 30 | have value n+1. 31 | Function till now has created the array, filled it with elements and now we return the address using return p. 32 | 33 | When we have any work with heap memory then we can use functions which return the address of that heap memory and it 34 | will be useful for calling function memory. So above is a method for return by address for a function. 35 | */ -------------------------------------------------------------------------------- /07. Functions/10. return_by_address.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int *fun() 9 | { 10 | /*int x = 10; 11 | // return &x; // Gives warning that address of stack memory associated with local variable 'x' returned. 12 | // This is not allowed as once the function ends then activation record of function will be deleted from the memory. 13 | */ 14 | 15 | // We are allocating heap memory and returning its address. Taking a pointer and creating int array. 16 | int *p = new int[5]; 17 | for (int i = 0; i < 5; i++) 18 | { 19 | // Store multiples of 5 in array. 20 | p[i] = 5 * i; 21 | } 22 | cout << "Address of p from function is : " << p << endl; // To show that address of p and q are same and indeed address of p is passed on to q when it calls fun. 23 | return p; // Initializes the array and function returns the address of memory allocated in heap to array. 24 | } 25 | 26 | int main() 27 | { 28 | int *q = fun(); //Declaring a pointer q in main function and call the function. Returning their addresses to see they're same. 29 | // Address of pointer will be stored in q in main, the address which we return as p from function. 30 | cout << "Address of q from main is : " << q; // To see if q has address same as what p has in the function and after activation record deletion of function 31 | // does that address gets passed on to the pointer which called the function i.e. pointer q. 32 | for (int i = 0; i < 5; i++) 33 | { 34 | cout << q[i] << endl; 35 | } 36 | 37 | return 0; 38 | } 39 | /* 40 | 41 | We can't use local variables such as int x = 10 and using return &x; 42 | Instead we should use heap memory and return address to that. 43 | 44 | p above creates the memory in heap and returns the address at the end of the function. 45 | That same address is passed on to q which we can verify on printing the addresses of pointers p and q which means 46 | q points to the same memory location. As heap memory is global to the program which means it can be accessed from any 47 | part of the program, provided address of that memory is known to us and precisely that is done by this function. 48 | It sends the address which is then used by q in the main function. 49 | */ -------------------------------------------------------------------------------- /07. Functions/11. return_by_reference.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | int &fun(int &x) // Writing a function which returns the reference 8 | { 9 | /*int x = 10; 10 | return x; // return by reference. Gives warning that local variable of function can't be returned as it's activation 11 | // record would be deleted when the function ends. It would cease to exist. So its reference can't be returned. 12 | // Reference can't be used to point to heap memory too. So how is it useful then...? 13 | */ 14 | 15 | return x; 16 | } 17 | using namespace std; 18 | int main() 19 | { 20 | int a = 10; 21 | fun(a) = 25; 22 | cout << a << endl; 23 | return 0; 24 | } 25 | 26 | /* 27 | Suppose we have a local variable in the main function named a with value 10, then we can call the function fun 28 | and we would pass the value a. We make the function fun take the reference variable x. 29 | 30 | When we have return by reference & then x variable will comeback where we call function as fun(a) and entire function 31 | becomes a reference. It will be a reference to local variable of main a. Main has a, a sent to function as x and x is 32 | reference to a. Here we take parameter as reference and return the same as a reference. 33 | */ -------------------------------------------------------------------------------- /07. Functions/12. local_global_variable.md: -------------------------------------------------------------------------------- 1 | ```c++ 2 | #include 3 | using namespace std; 4 | int g = 0; // Global variable 5 | void fun(){ 6 | int a = 5; // // Variable local to fun function 7 | g += a; 8 | cout << g; 9 | } 10 | int main() 11 | { 12 | int x = 10 ; // Variable local to main function 13 | return 0; 14 | } 15 | 16 | ``` 17 | 18 | | Local Variables | Global Variables | 19 | | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | 20 | | 1. Local variables aren't accessible in other functions.
Only belong to the functions in which they are declared. | 1. Global variables can be accessed through all teh functions of a program. | 21 | | 2. Remain in memory as long as function is running.
These terminate once the function ends. | 2. These exists as long as the program is running.
| 22 | | 3. These are created in stack section. | 3. These are present in code section and not in stack memory. | 23 | 24 |
Static Variables : These are variables which always reamins in the memory just as global variables only difference 25 |
being that global var can be accessed by any function but static variables are limited by their scope. 26 |
Static variable is created only once and isn't created everytime, even if the function it is in is called multiple times. 27 | -------------------------------------------------------------------------------- /07. Functions/13. scoping_rule.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | // global variable 10 | int x = 10; 11 | 12 | int main() 13 | { 14 | int x = 20; // Local to main function 15 | { 16 | int x = 30; // Local within scope, c++ has block level scope 17 | cout << "Output of x inside {} inside main : " << x << endl; // Gives output 30, i.e. nearest x value 18 | } 19 | cout << "Output of x outside {} but inside main : " << x << endl; // Gives output 20, i.e. nearest x value in its scope 20 | cout << "Output of global x using scope resolution operator :: " << ::x << endl; // Gives global output 10, i.e. global x value in its scope :: is scope resolution 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /07. Functions/14. static_variables.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | void fun() 9 | { // Function where we declare static integer. 10 | static int s = 10; 11 | s++; 12 | cout << "Value of s is : " << s; 13 | } 14 | 15 | int main() 16 | { 17 | for (int i = 0; i < 5; i++) 18 | { 19 | fun(); 20 | cout << " On Calling function fun() for " << i << "th time." << endl; 21 | // We see that static keeps increasing though activation record gets deleted but not for static. 22 | // On removing static we get 11 everytime and it will be erased with activation record. 23 | } 24 | 25 | return 0; 26 | } 27 | /* 28 | Static variables are useful inside the functions particularly in the modular or function based programming. 29 | */ -------------------------------------------------------------------------------- /07. Functions/15. recursive_function.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | void fun(int n) // Prints the int passed to the function till the value of that int is 1 or > 0. 10 | { 11 | if (n > 0) // Starts with 5, checks if 5 > 0, yes then prints 5, then calls for fun(4)..again checks and goes till 1. 12 | { 13 | cout << n << endl; 14 | fun(n - 1); 15 | } 16 | } 17 | 18 | int main() 19 | { 20 | int x = 5; 21 | fun(x); 22 | 23 | return 0; 24 | } 25 | /* 26 | RECURSIVE FUNCTION : Function which makes calls to itself as per a condition. Condition is required for every 27 | recursive function so that it can terminate after some calls and doesn't goes on infinitely. 28 | 29 | */ -------------------------------------------------------------------------------- /07. Functions/16. linear_search_function.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int search(int A[], int n, int key) 9 | 10 | { 11 | for (int i = 0; i < n; i++) 12 | { 13 | if (key == A[i]) 14 | return i; 15 | } 16 | return 0; 17 | } 18 | 19 | int main() 20 | { 21 | 22 | int Array[] = {23, 65, 89, 41, 69, 45, 91}; 23 | int number = 7; 24 | cout << "Elements of array are : " << endl; 25 | int i = 0; 26 | 27 | while (i != 7) 28 | { 29 | cout << Array[i] << "\t"; 30 | i++; 31 | } 32 | 33 | cout << "\nEnter the element you want to search for : "; 34 | int k; 35 | cin >> k; 36 | int index = search(Array, number, k); 37 | cout << "Element " << k << " found at index " << index << endl; 38 | return 0; 39 | } -------------------------------------------------------------------------------- /08. Intro to OOP/02. class_creation.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Rectangle // Defining a class 10 | { 11 | public: // Everything inside a class if not specified becomes private. 12 | // Put stuff in public for direct accessibility. 13 | int length, breadth; 14 | int area() 15 | { 16 | return length * breadth; 17 | } 18 | int perimeter() 19 | { 20 | return 2 * (length + breadth); 21 | } 22 | }; 23 | 24 | int main() 25 | { 26 | Rectangle r1, r2; // Creating instances or objects from class Rectangle 27 | r1.breadth = 5; 28 | r1.length = 10; 29 | r2.length = 20; // Using dot operator to access variables and allocate value 30 | r2.breadth = 30; 31 | cout << "Area of r1 is : " << r1.area() << endl; 32 | cout << "Perimeter of r2 is : " << r2.perimeter(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /08. Intro to OOP/03. pointer_to_object.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Rectangle // Defining a class 10 | { 11 | public: // Everything inside a class if not specified becomes private. 12 | // Put stuff in public for direct accessibility. 13 | int length, breadth; 14 | int area() 15 | { 16 | return length * breadth; 17 | } 18 | int perimeter() 19 | { 20 | return 2 * (length + breadth); 21 | } 22 | }; 23 | 24 | int main() 25 | { 26 | 27 | /* 28 | // Using arrow operator 29 | 30 | Rectangle r; // Creating instances or objects from class Rectangle in stack section 31 | Rectangle *p; // Pointer 32 | p = &r; // Pointer pointing on rectangle object r 33 | // r.breadth = 5; // Normal way to access variables of object 34 | // r.length = 10; 35 | p->length = 10; // Pointer way to acess variables of object using Arrow operator 36 | p->breadth = 5; 37 | // cout << "Area of r is : " << r.area() << endl; // Normal way 38 | // cout << "Perimeter of r is : " << r.perimeter(); 39 | cout << "Area of r is : " << p->area() << endl; // Using arrow -> operator, instead of * we can use arrow 40 | cout << "Perimeter of r is : " << p->perimeter(); // Arrow operator can be used to access data members and functions too. 41 | 42 | */ 43 | // Creating an object in heap - Dynamic Object in Heap 44 | Rectangle *p; 45 | p = new Rectangle; // p points to new object created in heap. 46 | // Doing it in one line 47 | Rectangle *q = new Rectangle; // Another object created in heap 48 | // Assigning value to objects in heap using arrow operator 49 | p->length = 5; 50 | p->breadth = 10; 51 | cout << "Area of r is : " << p->area() << endl; 52 | cout << "Perimeter of r is : " << p->perimeter() << endl; 53 | 54 | return 0; 55 | } 56 | 57 | /* 58 | Here we see how to have pointer on an object, and how to create objects in stack and heap memory. 59 | 60 | In JAVA objects can't be created in heap and are always created in heap using new. 61 | C++ gives option to programmer based on where you want object to be created. 62 | */ -------------------------------------------------------------------------------- /08. Intro to OOP/05. accessor_mutator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Rectangle // Defining a class 10 | { 11 | private: 12 | int length, breadth; // Direct access using objectName.dataMember is not allowed if you put variables in private 13 | 14 | public: 15 | int area() 16 | { 17 | return length * breadth; 18 | } 19 | int perimeter() 20 | { 21 | return 2 * (length + breadth); 22 | } 23 | // Making data accessible through functions 24 | void setLength(int l) // Mutator 25 | { 26 | if (l >= 0) // Validation code 27 | length = l; 28 | else 29 | length = 1; 30 | } 31 | void setBreadth(int b) // Mutator 32 | { 33 | if (b >= 0) // Validating the input 34 | breadth = b; 35 | else 36 | breadth = 1; // Assign length or breadth as 1 if input is found to be negative. 37 | } 38 | int getLength() // Accessor 39 | { 40 | return length; 41 | } 42 | int getBreadth() // Accessor 43 | { 44 | return breadth; 45 | } 46 | }; 47 | 48 | int main() 49 | { 50 | Rectangle r; // Creating instances or objects from class Rectangle 51 | r.setLength(5); 52 | r.setBreadth(10); 53 | 54 | cout << "Area of r is : " << r.area() << endl; 55 | cout << "Perimeter of r is : " << r.perimeter(); 56 | return 0; 57 | } 58 | 59 | /* 60 | 61 | 62 | */ -------------------------------------------------------------------------------- /08. Intro to OOP/07. deep_copy_constuctor.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Test 9 | { 10 | int a; 11 | int *p; 12 | 13 | public: 14 | Test(int x) // calling parameterized constructor. 15 | { 16 | a = x; 17 | p = new int[a]; 18 | } 19 | Test(Test &t) // Calling copy constructor 20 | { 21 | a = t.a; 22 | // p = t.p; // Wrong as it would point to array of the object it is copying. 23 | p = new int[a]; // Deep copy constructor. Think about deep copy constructor if there is dynamic memory allocation. 24 | // Also have a loop to copy stuff present in object which we copy. 25 | } 26 | }; 27 | 28 | int main() 29 | { 30 | Test t(5); 31 | Test t2(t); // Create another object t2 and pass t as an argument. Hence, copy constructor called here. 32 | return 0; 33 | } 34 | 35 | /* 36 | PROBLEM WITH COPY CONSTUCTOR : Inside main we create an object t with value as 5. t will have members a and p. 37 | We set x as 5 and a is assigned as 5. So our t.a is 5. and p = new int[a] means new array of size a i.e. 5 is created in 38 | heap memory and its address is stored in p. We created an object by calling parameterized constructor. 39 | 40 | After creation of t2 memory is created for a and p. What copy constructor does is it sets a of t2 as the a value of 41 | the argument passed to it. In this case t2.a = t.a = 5. and t2.p = t.p i.e. p of both t2 and t points to same array 42 | in heap memory. Which is wrong as object t2 should have it's own array of size same as t.p. 43 | Instead of creation of new array copy constructor points to the same array as of t instead of creating a new array for t2 44 | in the heap memory. That is what the problem is about using copy constructor. 45 | In case of dynamic memory allocation there are chances copy constructor may not create new memory for it and would just point 46 | to the object it is copying from. 47 | So we should write p = new int[a] inside the copy constructor too like we did for parameterized constructor. 48 | Image reference : https://i.imgur.com/JV08a1T.png 49 | */ -------------------------------------------------------------------------------- /08. Intro to OOP/08. function_in_class.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Rectangle 9 | { 10 | private: 11 | int length, breadth; 12 | 13 | public: 14 | Rectangle() // Non parameterized constuctor. 15 | { // Constructor has same name as class and they don't have any return type. 16 | length = 1; 17 | breadth = 1; 18 | } 19 | // Parameterized Constructor 20 | Rectangle(int l, int b) // Doing so compared to what is above is better as it eliminates use of non parameterized constructor by setting default values of l and b if no values are passed by user. 21 | { 22 | setLength(l); // Calling set length and set breadth as these functions have validation inside them 23 | setBreadth(b); 24 | } 25 | Rectangle(Rectangle &rect) // Copy constructor : We pass in another constructor as parameter. 26 | { 27 | length = rect.length; 28 | breadth = rect.breadth; 29 | } 30 | // Mutators / Setter methods 31 | void setLength(int l) 32 | { 33 | if (l >= 0) 34 | length = l; 35 | else 36 | length = 0; 37 | } 38 | void setBreadth(int b) 39 | { 40 | if (b >= 0) 41 | breadth = b; 42 | else 43 | breadth = 0; 44 | } 45 | // Accessors / Getter methods 46 | int getLength() 47 | { 48 | return length; 49 | } 50 | 51 | int getBreadth() 52 | { 53 | return breadth; 54 | } 55 | // Facilitators 56 | int area() 57 | { 58 | return length * breadth; 59 | } 60 | int perimeter() 61 | { 62 | return 2 * (length + breadth); 63 | } 64 | 65 | // Inspector function 66 | // bool isSquare(); 67 | //Destructor function 68 | // ~Rectangle(); 69 | }; 70 | 71 | int main() 72 | { 73 | 74 | Rectangle r(10, 5); 75 | 76 | cout << "Area is : " << r.area() << endl; 77 | cout << "Length of Rectangle is : " << r.getLength() << endl; 78 | 79 | Rectangle r2(r); 80 | 81 | return 0; 82 | } 83 | /* 84 | The functions we define above for a class these aren't mandatory but creating these in a class would lead 85 | to creation of a perfect class. Writing these methods is just same as following pep8 for python or can be said to have 86 | a good standard code guidelines which makes it easy for program in every way. 87 | 88 | So our class should have the following functions in our class irrespective of need to create a perfect class : 89 | 90 | 1. Constructors 91 | 1.1 Non parameterized constructor 92 | 1.2 Parameterized constructor 93 | 1.3 Copy constructor 94 | -------------------------------------------------------------- 95 | 2. Setter or mutators 96 | 3. Accessors or Getters 97 | 4. Actual functions useful for class called Facilitators 98 | 5. Inspector function -> Checks based on some properties, mostly a bool 99 | 6. Destructor function 100 | 101 | In a class we just write the function names and do not define the functions inside it without ellaborating. 102 | Functions are ellaborated outside the class by using scope resolution operators. 103 | 104 | */ -------------------------------------------------------------------------------- /08. Intro to OOP/09. scope_resolution.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Rectangle 9 | { 10 | private: 11 | int length, breadth; 12 | 13 | public: 14 | Rectangle(); 15 | Rectangle(int l, int b); 16 | Rectangle(Rectangle &r); 17 | int getLength() { return length; } // In-line functions 18 | int getBreadth() { return breadth; } 19 | void setLength(int l); 20 | void setBreadth(int b); 21 | int area(); 22 | int perimeter(); 23 | bool isSquare(); 24 | ~Rectangle(); 25 | }; 26 | 27 | int main() 28 | { 29 | Rectangle r(10, 10); 30 | cout << "Area is " << r.area() << endl; 31 | if (r.isSquare()) 32 | cout << "Yes given rectangle of length " << r.getLength() << " and breadth " << r.getBreadth() << " is a square."; 33 | // Automatically destructor is called and displays message. 34 | return 0; 35 | } 36 | 37 | Rectangle::Rectangle() 38 | { 39 | length = 1; 40 | breadth = 1; 41 | } 42 | 43 | Rectangle::Rectangle(int l, int b) 44 | { 45 | setLength(l); 46 | setBreadth(b); 47 | } 48 | 49 | Rectangle::Rectangle(Rectangle &rect) 50 | { 51 | length = rect.length; 52 | breadth = rect.breadth; 53 | } 54 | 55 | void Rectangle::setLength(int l) 56 | { 57 | if (l >= 0) 58 | length = l; 59 | else 60 | length = 0; 61 | } 62 | 63 | void Rectangle::setBreadth(int b) 64 | { 65 | if (b >= 0) 66 | breadth = b; 67 | else 68 | breadth = 0; 69 | } 70 | 71 | int Rectangle::area() 72 | { 73 | return length * breadth; 74 | } 75 | 76 | int Rectangle::perimeter() 77 | { 78 | return 2 * (length + breadth); 79 | } 80 | 81 | bool Rectangle::isSquare() 82 | { 83 | return length == breadth; 84 | } 85 | 86 | Rectangle::~Rectangle() 87 | { 88 | cout << "Rectangle Destroyed."; 89 | } -------------------------------------------------------------------------------- /08. Intro to OOP/10. this_pointer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Rectangle 9 | { 10 | private: 11 | int length, breadth; 12 | 13 | public: 14 | Rectangle(int length, int breadth) 15 | { 16 | this->length = length; 17 | this->breadth = breadth; 18 | } 19 | int area() 20 | { 21 | return length * breadth; 22 | } 23 | int perimeter() 24 | { 25 | return 2 * (length + breadth); 26 | } 27 | }; 28 | 29 | int main() 30 | { 31 | Rectangle r1(10, 5); // 10 and 5 goes to length and breadth of function and via this gets stored in private members. 32 | return 0; 33 | } 34 | /* 35 | It would be more readable for us to have constructor which goes like 36 | 37 | Rectangle(int length, int breadth) 38 | { 39 | length = length; 40 | breadth = breadth; 41 | } 42 | //The above length = length won't make sense as we don't know which length is being assigned to which variable. 43 | To avoid ambiguity and make the name statement more clear we use this->length. 44 | this->length is the pointer to the length which is inside private in the class. Same goes for this->breadth the breadth 45 | pointer which is made private. And we assign the values which are being passed into the function to those. 46 | 47 | this-> pointer is used to remove the ambiguity between parameters of functions and data members of a class. 48 | this-> is used to refer to the data member of current class we are writing this in. 49 | After creating the object r1 this->length is read as length of r1 and same goes for breadth. 50 | */ -------------------------------------------------------------------------------- /08. Intro to OOP/11. struct_class.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | struct Demo 9 | { 10 | int x, y; 11 | 12 | void Display() 13 | { 14 | cout << x << " " << y << endl; 15 | } 16 | }; 17 | 18 | int main() 19 | { 20 | Demo d; 21 | d.x = 10; 22 | d.y = 15; 23 | d.Display(); 24 | return 0; 25 | } 26 | /* 27 | Data members can't be private or protected in a structure as opposed to a class. Also in C we can't have functions inside 28 | structures. In C++ structure is somewhat like class. Difference between the two being in class everything is private by 29 | default, which is not the case for class. Difference being structure has everything by default as public and class has 30 | everything by default as private. 31 | */ -------------------------------------------------------------------------------- /08. Intro to OOP/12. student_exercise.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Student 9 | { 10 | private: 11 | int roll; 12 | string name; 13 | int math_marks, phy_marks, chem_marks; 14 | 15 | public: 16 | Student(int roll, string name, int phy_marks, int chem_marks, int math_marks); 17 | void set_math(int math_marks); 18 | void set_phy(int phy_marks); 19 | void set_chem(int chem_marks); 20 | 21 | int get_math() { return math_marks; } 22 | int get_phy() { return phy_marks; } 23 | int get_chem() { return chem_marks; } 24 | 25 | int total(); 26 | 27 | char grade(); 28 | }; 29 | 30 | int main() 31 | { 32 | int roll; 33 | string name; 34 | int p, c, m; 35 | cout << "Enter Roll Number of Student : "; 36 | cin >> roll; 37 | cout << "Enter name of the student"; 38 | cin >> name; 39 | cout << "Enter marks in 3 subjects : "; 40 | cin >> p >> c >> m; 41 | Student s(roll, name, p, c, m); 42 | cout << "Total Marks : " << s.total() << endl; 43 | cout << "Grade of " << name << " is : " << s.grade() << endl; 44 | return 0; 45 | } 46 | 47 | Student::Student(int roll, string name, int phy_marks, int chem_marks, int math_marks) 48 | { 49 | this->roll = roll; 50 | this->name = name; 51 | this->math_marks = math_marks; 52 | this->phy_marks = phy_marks; 53 | this->chem_marks = chem_marks; 54 | } 55 | int Student::total() 56 | { 57 | return math_marks + phy_marks + chem_marks; 58 | } 59 | char Student::grade() 60 | { 61 | { 62 | float average = total() / 3; 63 | if (average > 60) 64 | return 'A'; 65 | else if (average >= 40 && average < 60) 66 | return 'B'; 67 | else 68 | return 'C'; 69 | } 70 | } 71 | 72 | void Student::set_math(int math_marks) 73 | { 74 | if (math_marks >= 0) 75 | this->math_marks = math_marks; 76 | else 77 | this->math_marks = 0; 78 | } 79 | void Student::set_phy(int phy_marks) 80 | { 81 | if (phy_marks >= 0) 82 | this->phy_marks = phy_marks; 83 | else 84 | this->phy_marks = 0; 85 | } 86 | void Student::set_chem(int chem_marks) 87 | { 88 | if (chem_marks >= 0) 89 | this->chem_marks = chem_marks; 90 | else 91 | this->chem_marks = 0; 92 | } 93 | /* 94 | 95 | Write a class student with following : 96 | 1. Roll 97 | 2. Name 98 | 3. Marks in 3 subject 99 | 100 | Functions for total marks, Grade and required methods. 101 | 102 | */ -------------------------------------------------------------------------------- /09. Operator Overloading/01. operator_overloading.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Complex 10 | { 11 | private: 12 | int real, img; 13 | 14 | public: 15 | Complex(int real = 0, int img = 0) // 0 if nothing is passed 16 | { 17 | this->real = real; 18 | this->img = img; 19 | } 20 | // Complex add(Complex x) // Normal way 21 | Complex operator+(Complex x) 22 | { // Signature of add function 23 | Complex temp; 24 | temp.real = this->real + x.real; 25 | temp.img = this->img + x.img; 26 | return temp; 27 | } 28 | int get_real() 29 | { 30 | return this->real; 31 | } 32 | int get_img() 33 | { 34 | return this->img; 35 | } 36 | }; 37 | 38 | int main() 39 | { 40 | Complex c1(5, 7), c2(2, 9), c3; 41 | // c3 = c1.add(c2); // Old method 42 | c3 = c1 + c2; // Using operator overloading 43 | cout << "Sum of c1(5,7) and c2(5,9) complex numbers is : " << c3.get_real() << " + " << c3.get_img() << "i as sum."; 44 | return 0; 45 | } 46 | 47 | /*In C++ there are operators for various operations like +,-,*,/,new,delete etc. 48 | These operators are meant for some specific data type. There are built-in operators for built-in data types. 49 | Say + can be used by-default only with int or float data type only. If we are defining our own data type say a class 50 | called matrix and we want + operator to add 2 matrices A and B and store it in C ? 51 | Yes, with the help of operator overloading we can do so. + operator can be overloaded for matrix. 52 | For user defined data type we can overload operators. There are various operators we can overload in C++ except a few. 53 | 54 | We here try to add 2 complex numbers c1 and c2 and show sum as c3 by overloading + operator. 55 | c3 = c1+c2 where c1 = 5+7i and c2 = 2+9i and c3 comes comes out to be 7+16i. 56 | 57 | For operator overloading two things are needed : 58 | 1. How to write functions 59 | 2. Signature of a function 60 | 61 | Say we are inside main 62 | int main(){ 63 | Complex c1(5,7); // makes complex number object c1 64 | Complex c2(2,9); 65 | Complex c3; 66 | // What we want is c3 = c1+c2 . c1 to c3 all are objects of class complex. Now how the addition would happen ? 67 | // Instead of + we do the following 68 | c3 = c1.add(c2) // c1 will add 2 complex numbers and will take c2 as parameter. Now we define add function in class 69 | } 70 | This was the logic now we move towards operator overloading part. 71 | Now where we have defined the function as Complex add(Complex x) there instead of add we write operator+ as follows : 72 | Complex operator+(Complex x) and this can be called not as c3 = c1.operator+(c2) but as c3 = c1 + c2 73 | */ -------------------------------------------------------------------------------- /09. Operator Overloading/02. friend_operator_overloading.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Complex 10 | { 11 | private: 12 | int real, img; 13 | 14 | public: 15 | Complex(int real = 0, int img = 0) // 0 if nothing is passed 16 | { 17 | this->real = real; 18 | this->img = img; 19 | } 20 | // Friend function's prototype 21 | friend Complex operator+(Complex x, Complex y); // Friend function has to be written outside the class. 22 | // Should return Complex only and takes 2 complex #'s as parameters, add them and return result in another Complex object 23 | int get_real() 24 | { 25 | return this->real; 26 | } 27 | int get_img() 28 | { 29 | return this->img; 30 | } 31 | }; 32 | 33 | int main() 34 | { 35 | Complex c1(5, 7), c2(2, 9), c3; 36 | // c3 = c1.add(c2); // Old method 37 | c3 = c1 + c2; // Using operator overloading 38 | cout << "Sum of c1(5,7) and c2(5,9) complex numbers is : " << c3.get_real() << " + " << c3.get_img() << "i as sum."; 39 | return 0; 40 | } 41 | 42 | Complex operator+(Complex c1, Complex c2) // Independent function doesn't belongs to class but if friend of the class. 43 | //That is the reason why scope resolution is not used here. 44 | { 45 | Complex t; 46 | t.real = c1.real + c2.real; 47 | t.img = c1.img + c2.img; 48 | return t; 49 | } 50 | /* 51 | We have seen how to overload an operator. There is another way as well for overloading an operator using friend function. 52 | Here also we want to do c3 = c1 + c2. In operator overloading either c1 was calling c2 as argument or vice-versa. 53 | 54 | Suppose 2 person have some money and they want to know total amount they both have. Either A can take B's money and find total 55 | or B can take A's money and find total. This is what kind of happens in operator overloading. 56 | 57 | Or what we can do is call a third person and tell him to take Money of A and B and tell the total. This is what happens 58 | when we use friend function. Above we can see how to make this friend function. 59 | 60 | */ -------------------------------------------------------------------------------- /09. Operator Overloading/03. insertion_operator_overloading.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Complex 10 | { 11 | private: 12 | int real, img; 13 | 14 | public: 15 | Complex(int real = 0, int img = 0) // 0 if nothing is passed 16 | { 17 | this->real = real; 18 | this->img = img; 19 | } 20 | // Complex add(Complex x) // Normal way 21 | Complex operator+(Complex x) 22 | { // Signature of add function 23 | Complex temp; 24 | temp.real = this->real + x.real; 25 | temp.img = this->img + x.img; 26 | return temp; 27 | } 28 | int get_real() 29 | { 30 | return this->real; 31 | } 32 | int get_img() 33 | { 34 | return this->img; 35 | } 36 | /* void display() // To display a complex number, now we want cout << c1; to have result same as c1.display() 37 | {//So, we have to overload the insertion operator, for that we build the function prototype 38 | cout << this->real << " + " << this->img << "i"; 39 | } */ 40 | friend ostream &operator<<(ostream &o, Complex &c1); // Friend function has to be outside the class 41 | }; 42 | 43 | int main() 44 | { 45 | Complex c1(5, 7), c2(2, 9), c3; 46 | // c3 = c1.add(c2); // Old method 47 | c3 = c1 + c2; // Using operator overloading 48 | cout << c1; 49 | cout << c2; 50 | cout << "Sum of c1(5,7) and c2(5,9) complex numbers is : " << c3.get_real() << " + " << c3.get_img() << "i as sum."; 51 | return 0; 52 | } 53 | 54 | ostream &operator<<(ostream &o, Complex &c1) 55 | { 56 | o << "Complex number is : "; 57 | o << c1.real << " + " << c1.img << "i" << endl; 58 | return o; 59 | } 60 | /* 61 | We can overload output stream or ostream operator as well. We use cout and cin i.e. instream and outstream for things 62 | like displaying the values or taking the input from the user. These extraction and insertion operators can also be over- 63 | -loaded. We will see overloading of insertion operator class here. 64 | We have a class Complex and in main there is object. If we have int x = 10. And we did cout< 7 | using namespace std; 8 | 9 | class Rational 10 | { 11 | private: 12 | int p, q; 13 | 14 | public: 15 | // Non parameterized constructor made useless by setting p and q = 1 in the constructor below 16 | /*Rational() 17 | { 18 | p = 1; 19 | q = 1; 20 | } */ 21 | Rational(int p = 1, int q = 1) // Parameterized constructor 22 | { 23 | this->p = p; 24 | this->q = q; 25 | } 26 | Rational(Rational &r) // Copy constructor 27 | { 28 | this->p = r.p; 29 | this->q = r.q; 30 | } 31 | int get_p() { return p; } 32 | int get_q() { return q; } 33 | void set_p(int p) 34 | { 35 | this->p = p; 36 | } 37 | void set_q(int q) 38 | { 39 | this->q = q; 40 | } 41 | Rational operator+(Rational r) 42 | { 43 | Rational temp; 44 | temp.p = this->p * r.q + this->q * r.p; // Numerator part 45 | temp.q = this->q * r.q; // Denominator part 46 | return temp; // Return numerator and denominator together 47 | } 48 | friend ostream &operator<<(ostream &os, Rational &r); 49 | }; 50 | 51 | int main() 52 | { 53 | Rational r1(3, 4), r2(2, 5), r3; 54 | r3 = r1 + r2; 55 | cout << "Sum of " << r1 << " and " << r2 << " is " << r3 << endl; 56 | return 0; 57 | } 58 | 59 | ostream &operator<<(ostream &os, Rational &r) 60 | { 61 | os << r.p << "/" << r.q; 62 | return os; 63 | } 64 | /* 65 | Here we write a class Rational and use operator overloading on + and insertion operator to display the sum. 66 | */ -------------------------------------------------------------------------------- /10. Inheritance/01. inheritance.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Base 10 | { 11 | public: 12 | void display() 13 | { 14 | cout << "Display function called of class Base." << endl; 15 | } 16 | }; 17 | 18 | class Derived : public Base // Publicly inheriting from class base to new class derived. 19 | { 20 | public: 21 | void show() 22 | { 23 | cout << "Show of derived." << endl; 24 | } 25 | }; 26 | 27 | int main() 28 | { 29 | Base b; 30 | cout << "On calling display through object of class base gives us : " << endl; 31 | b.display(); 32 | Derived d; 33 | cout << "On calling display through object of derived base gives us : " << endl; 34 | d.display(); 35 | cout << "On calling show function of derived class through object of class derived gives us : " << endl; 36 | d.show(); 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /10. Inheritance/03. constructors_in_inheritance.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class parent_class 9 | { 10 | public: 11 | parent_class() 12 | { 13 | cout << "Default constructor called of class parent.\n"; 14 | } 15 | parent_class(int x) 16 | { 17 | cout << "Parameterized constructor called of class parent and x = " << x << endl; 18 | } 19 | }; 20 | //------------------------------------------------------------------------------------------- 21 | class child_class : public parent_class 22 | { 23 | public: // Here also we write nothing but constructors 24 | child_class() 25 | { 26 | cout << "Default constructor called of class child.\n"; 27 | } 28 | child_class(int a) 29 | { 30 | cout << "Parameterized constructor called of class child and x = " << a << "." << endl; 31 | } 32 | // to call the parameterized constructor of parent class when the object of child class is executed 33 | child_class(int x, int a) : parent_class(x) 34 | { 35 | cout << "Param of child class is a = " << a; 36 | /* What about x ? How to send the parameter to parent_class from child ? for that do :parent_class(x) 37 | So, from child class constructor here we call the constructor of parent class which is parameterized constructor. */ 38 | } 39 | }; 40 | int main() 41 | { 42 | // Create object of class child_class to see how the constructors are executed 43 | // child_class object(20); // Calls non param const of parent and param. const of child class. 44 | 45 | // child_class object; 46 | /* Created object of class child_class without parameters hence trying to call non param. contructor. 47 | But here by default constructor of parent class non parameterized one will be executed. 48 | We would get Default of parent_class output and then we will get Default const..... of class child_class.*/ 49 | child_class(20, 10); // parent_class(20) and child_class(10) is called. 50 | 51 | return 0; 52 | } 53 | 54 | /* 55 | Above we make a simple class parent_class and inside it we only write constructors of different kinds. 56 | Whenever dealing with inheritance of classes just know that the parent class constructor will be executed first and 57 | then child class constructor would be executed when creating object of child class. 58 | 59 | On passing a parameter to the derived class object, we are trying to create an object using parameterized constructor 60 | for creating object of Derived class. So, here first parent_class class default constructor will be executed first and after that 61 | parameterized constructor of child_class is executed. 62 | 63 | How to call the parameterized constructor of parent class when the object of child class is executed ? 64 | For that we need to have special constructor in child class. 65 | */ -------------------------------------------------------------------------------- /10. Inheritance/04. isA_hasA_relation.md: -------------------------------------------------------------------------------- 1 | # isA vs hasA Relationship 2 | 3 | This concept is useful for understanding access specifiers in C++ and applies to Object Orientation in general. 4 | Helps us to understand accessibility of members of a class. 5 | 6 | ## Class can be used in 2 ways : 7 | 8 | **(i) By inheriting/deriving ** 9 | 10 | **(ii) By creating its object** 11 | 12 | Say we have a class Rectangle and from that we make a class called Cuboid which inherits Rectangle publicly. 13 | So, here we can say that since Cuboid inherits rectangle so Cuboid can be considered as modified Rectangle only. 14 | So, when we inherit a class we will say that Cuboid is a **(isA)** Rectangle. 15 | 16 | See another example, say there is separate class Table Rectangle top as an object among other functions. 17 | Here we say that as Table class uses object of Rectangle named top we consider it as Table has a Rectangle. 18 | So, when we use a class by creating an object of that class then we will say that Table has a **(hasA)** Rectangle. 19 | 20 | Classes can have data members of 3 kinds **(i) Public (ii) Private (iii) Protected** 21 | 22 | Next we see which members are accessible inside in isA relationship vs accessibility in hasA relation. 23 | What is accessible inside the class, what can be accessed from derived classes and what is accessible upon objects. 24 | We will understand what is the effect of access specifiers in C++. -------------------------------------------------------------------------------- /10. Inheritance/05. access_specifier.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Parent 9 | { 10 | private: 11 | int a; 12 | 13 | protected: 14 | int b; 15 | 16 | public: 17 | int c; 18 | void fun_parent() 19 | { 20 | this->a = 10; 21 | this->b = 20; 22 | this->c = 30; 23 | } 24 | }; 25 | 26 | class Child : Parent 27 | { 28 | public: 29 | void fun_derived() 30 | { // Function which accesses members of parent but can access protected not private. 31 | //When we say Child is inherited from Parent then all members are available here as well of parent. 32 | b = 2; 33 | c = 3; 34 | // Private is available but not accessible through child, public and protected are accessible via child too in a class. 35 | } 36 | }; 37 | 38 | int main() 39 | { 40 | Parent x; // x initialized with data members a,b and c. Out of these 3 we can directly only access c as it is public. 41 | // for a and b all read and write options needs to be done through public functions in the class. 42 | 43 | return 0; 44 | } 45 | /* 46 | Public, private and protected are access specifiers in C++. 47 | Above we create a parent class with members of all 3 kinds of access specifiers. We have a function which is assigning 48 | values to the variables declared. 49 | So, idea behind making only public accessible in an object is that when making an object and as programmer 50 | we want some stuff not to be interfered with, components which are crucial for working of code we set them as private. 51 | When programmer wants to allow others to modify or access something then we set it as public or protected. 52 | 53 | Say one of the program is given directly to a client. That is object was made from our design class and we do not 54 | want user to interfere with internal mechanisms and provide user just barebone so that all his functionalities are 55 | accessible to him and nothing else. So we set those things as public. Like in a TV we do not allow directly circuit 56 | to be interfered with rather we have functions for volume or channel change just like that we make selective stuff 57 | which we want intentionally for user to get his/her hands on as public rest is kept out of the access when it is an object 58 | that is given to user. 59 | 60 | For reference : https://i.imgur.com/CVKqCtm.png 61 | */ -------------------------------------------------------------------------------- /10. Inheritance/06. access_specifier.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Rectangle 10 | { 11 | private: // Data members as private 12 | int length; 13 | int breadth; 14 | 15 | public: // Members functions as public 16 | int area() 17 | { 18 | return length * breadth; 19 | } 20 | int perimeter() 21 | { 22 | return 2 * (length + breadth); 23 | } 24 | void set_length(int length) 25 | { 26 | (length > 0) ? this->length = length : this->length = 0; 27 | } 28 | void set_breadth(int breadth) 29 | { 30 | (breadth > 0) ? this->breadth = breadth : this->breadth = 0; 31 | } 32 | int get_length() { return this->length; } 33 | int get_breadth() { return this->breadth; } 34 | }; 35 | 36 | int main() 37 | { 38 | Rectangle r1; 39 | r1.set_breadth(5); 40 | r1.set_length(6); 41 | cout << "Area is : " << r1.area() << endl; 42 | cout << "Length is : " << r1.get_length() << endl; 43 | cout << "Breadth is : " << r1.get_breadth() << endl; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /10. Inheritance/07. types_of_inheritance.md: -------------------------------------------------------------------------------- 1 | # Types of Inheritance : 2 | 3 | 1. ### Single / Simple Inheritance : 4 | 5 | If we have class A as parent having class B as it's child class . So, class B is inheriting from existing class. This is single/simple inheritance. 6 | 7 | 2. ### Hierarchical Inheritance 8 | 9 | If we have class A and from this class more than 1 class i.e. class B, C and D are inheriting then this is called Hierarchical Inheritance. 10 | 11 | 3. ### Multilevel Inheritance 12 | 13 | If there is a parent class A and from that class there is class B is inheriting and from class B there is class C inheriting then this is known as Multilevel inheritance. 14 | 15 | 4. ### Multiple Inheritance 16 | 17 | If there are 2 classes A and B on the same level and from both of them a single class is inheriting i.e. class C then this is called Multiple Inheritance. This is a unique kind of inheritance supported in C++. This is not allowed in JAVA. Due to this for one class there can be one or more base classes. 18 | 19 | 5. ### Hybrid Inheritance 20 | 21 | There is another kind of inheritance known as hybrid inheritance where we mix different kinds of inheritance models known to us. 22 | 23 | Mixing of hierarchical and multiple or various other kinds of inheritance together gives us hybrid inheritance. Say from parent class A there is inheritance of base classes B and C, and from these two there is another class which inherits i.e. D. This is an example of hybrid inheritance. Where from top we see hierarchical inheritance and at the bottom it is multiple inheritance. This type of inheritance is unique to C++ but on having this kind of inheritance then features of base class A will appear in D via B and C both. Say A has function fun() then this function will be available via B and C class to class D. On calling the function we see there are 2 copies of functions in D which comes from B and C. This is what is known as multi-path inheritance. 24 | 25 | Here ambiguity we face is to call fun( ) function via B or C. To tackle this we have concept of virtual base classes. 26 | 27 | ```c++ 28 | class A { 29 | // Some stuff inside the class. 30 | }; 31 | class B : virtual public A // See here we use virtual 32 | { 33 | // Some more stuff inside the class. 34 | }; 35 | class C : virtual public A // Another class same as B 36 | { 37 | 38 | }; 39 | class D : public B, public C 40 | { 41 | // Due to writing virtual then ambiguity is removed of function appearing via B or C 42 | }; 43 | ``` 44 | 45 | When developing one's own project and there needs to be an organization of classes and levels of inheritance for that we have different kinds of inheritance models we saw above. 46 | 47 | [Reference Image](https://i.imgur.com/cfPdPtd.png) 48 | -------------------------------------------------------------------------------- /10. Inheritance/08. Ways of Inheritance.md: -------------------------------------------------------------------------------- 1 | There are more than one way of deriving a child class from parent class. There are multiple methods to do so. There are 3 methods of inheritance i.e.. public, private and protected. By default everything in a class is private. 2 | 3 | ```c++ 4 | class child : public Parent 5 | ``` 6 | 7 | Say there is a class called Parent and has 3 members, private, protected and public. We have a class called child which publicly inherits from the Parent class. Child also has 3 members, private, protected and public. On inheriting from parent class everything is available in children class but only protected and public members are accessible. Protected becomes protected on coming to child class and public element of parent stays public in child class. 8 | 9 | If we create a class GrandChild which inherits from child class, then inside GrandChild class protected and public are accessible. 10 | 11 | If we make inheritance of parent as protected as follows : 12 | 13 | ```c++ 14 | class child : protected Parent 15 | class GrandChild : public child 16 | ``` 17 | 18 | Then protected member stays protected but the public member of Parent class also becomes protected. When GrandChild class inherits from the public child then also public of parent will be inherited in GrandChild as protected. 19 | 20 | Way of inheritance affects the objects and grand child classes or sub classes which are subsequently formed. 21 | 22 | On making class being inherited as private as follows : 23 | 24 | ```c++ 25 | class child : private Parent 26 | class GrandChild : public child 27 | ``` 28 | 29 | Doing above leads to both protected and public members of Parent class becoming private. So due to that GrandChild is unable to access any of the members of the Parent class. -------------------------------------------------------------------------------- /10. Inheritance/09. inheritance_method.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Parent 9 | { 10 | private: 11 | int a; 12 | 13 | protected: 14 | int b; 15 | 16 | public: 17 | int c; 18 | void parent_function() 19 | { 20 | a = 10; 21 | b = 5; 22 | c = 15; 23 | } 24 | }; 25 | 26 | // class Child : public Parent // inheriting to Child class from Parent publicly. 27 | // class Child : protected Parent // Inheriting as protected and all members of Parent comes under protected 28 | class Child : private Parent // Inheriting as private and all members of Parent comes under private 29 | { 30 | protected: 31 | // Anything inside protected is accessible inside the same class but further Grand_Child class will be able to access 32 | // all protected and public members when inheriting from Child class. Same goes for inheriting Parent privately. 33 | public: 34 | void child_function() 35 | { 36 | // a = 10; // Inaccessible due to a being private in class Parent 37 | b = 5; 38 | c = 15; 39 | } 40 | }; 41 | 42 | class Grand_Child : public Child 43 | { 44 | public: 45 | void grand_child_function() 46 | { 47 | // a = 10; // Inaccessible due to a being private in class Parent 48 | b = 16; 49 | c = 20; 50 | } 51 | }; 52 | 53 | int main() 54 | { 55 | Child c; 56 | // c.b = 12; // Commented out as not accessible due to being private 57 | // c.a = 10; // Commented out as not accessible due to being protected 58 | // c.c = 14; // Commented out as not accessible after inheriting parent as protected. 59 | return 0; 60 | } 61 | 62 | /* 63 | Derived class can inherit from base class using 3 methods private, public and protected. 64 | Above we have parent class which has some members as one of every access specifier kind. 65 | It has a function as well which accesses all the members. 66 | 67 | Then we have a child class which inherits from Parent publicly. Child class has a function 68 | which tries to access members which are being inherited from parent class. 69 | We see that a is not accessible inside the child function so we comment it. 70 | 71 | For explanation about various methods of inheritance of a class public, pvt. and protected we 72 | take another class called grand_child, this class inherits from child class, here also we write 73 | the same function as child class which tries to access variables of class Parent, and even child class does not own 74 | these members which are being called in grand_child class from child class. As a,b,c are members of Parent class. 75 | 76 | Let's look at method of inheritance which is publicly. When child class inherits publicly then all the members of 77 | the parent class are taken as it is from parent to child class. Same happens when grand_child class inehrits 78 | child class then also var a is not accessible as it is private in Parent class. 79 | 80 | We verify the same by creating an object of child class and accessing variables of Class Child. Upon trying to modify 81 | the a and b variable we get an error that we cannot access a and b which are private and protected which comes from Parent. 82 | 83 | Object of child is not accessible from main function as the members were made protected when inheriting from Parent. 84 | */ -------------------------------------------------------------------------------- /10. Inheritance/10. Generalization vs specialization.md: -------------------------------------------------------------------------------- 1 | # Generalizations vs Specialization 2 | 3 | This is a topic related to inheritance. We have a class Rectangle and we are able to create object of rectangle and we can use it by calling the functions area and parameters. Then we have a class for cuboid and this class inherits the class Rectangle. Cuboid can also call the functions and create its own objects. In this case Rectangle was existing and from there we have derived cuboid. So rectangle class was already existing and we have defined a new class with extra features, a specialized class which is cuboid. Something already exits and you derive the existing class add some more features and this leads to extending of functionality is specialization class. 4 | 5 | Say is a class acting as Parent named Shapes for the classes Rectangle, Circle and Quadrilateral. These 3 classes inherit from Shape. So Shape might not exist in real world, it is just a virtual term and on being asked to use a shape then user would draw some instance of shape circle, rectangle but cannot show a shape directly. Something named shape doesn't exist it is just a generalization of various kinds of shapes. We use generalization to bring the classes which are already existing under one common umbrella. Say car Innova, Duster, Fortuner etc. are specific car objects can be said as specialization of some old car model and all these can be generalized under umbrella of Cars which is the generalization of the 3 cars models mentioned above. A group of class when given a general term easy for reference or a super class which contains all similar classes which can be identified by common name is what's called Generalization of classes. If parent exists and child inherits from parent then that top down approach is **Specialization** as we saw in Rectangle -> Cuboid case. If children elements are integrated into one big parent umbrella after they were created that is the case of **Generalization**. In generalization base class doesn't have anything to give to child class, it's only purpose is to put children into one super class which can be used to reference similar kinds of classes. Generalization is needed for polymorphism. That is same name but different objects and different actions. 6 | 7 | Purpose of generalization is to achieve polymorphism and purpose of specialization is to give its child elements some features as parent. So this answers the question that purpose of Inheritance are 2 basic things : Sharing features to child classes and second is to achieve polymorphism. -------------------------------------------------------------------------------- /10. Inheritance/11. student_exercise.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Employee // Employee class with Employee ID and name 10 | { 11 | private: 12 | int eid; 13 | string name; 14 | 15 | public: 16 | Employee(int eid, string name) // Constructor 17 | { 18 | this->eid = eid; 19 | this->name = name; 20 | } 21 | 22 | int get_employee_id() { return eid; } // Accessor 23 | string get_name() { return name; } 24 | }; 25 | 26 | class Full_Time_Employee : public Employee // Full_Time_Employee inheriting from Employee and has salary as data member. 27 | { 28 | private: 29 | int salary; 30 | 31 | public: 32 | Full_Time_Employee(int eid, string name, int salary) : Employee(eid, name) // Call parameterized constructor of Employee 33 | { 34 | this->salary = salary; 35 | } 36 | int get_salary() { return salary; } 37 | }; 38 | 39 | class Part_Time_Employee : public Employee 40 | { 41 | private: 42 | int daily_wage; 43 | 44 | public: 45 | Part_Time_Employee(int eid, string name, int daily_wage) : Employee(eid, name) 46 | { 47 | this->daily_wage = daily_wage; 48 | } 49 | int get_wage() { return daily_wage; } 50 | }; 51 | 52 | int main() 53 | { 54 | Part_Time_Employee p1(0001, "Cosmic", 300); 55 | Full_Time_Employee p2(0002, "Commander", 50000); 56 | cout << "Salary of " << p2.get_name() << " is " << p2.get_salary() << endl; 57 | cout << "Daily Wage of " << p1.get_name() << " is " << p1.get_wage() << endl; 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /11. Base Class Pointer Derived Class Object/01. Base Class Pointer Derived Class Object.md: -------------------------------------------------------------------------------- 1 | Say we have a base class with functions as follows : 2 | 3 | ```c++ 4 | class Base 5 | { 6 | public: 7 | void func1(); 8 | void func2(); 9 | void func3(); 10 | }; // Base class with 3 functions created 11 | class Child : public Base { // Class child inheriting from Base publicly 12 | public: 13 | void func4(); // Child class also has 2 additional functions along with 3 of class Base 14 | void func5(); 15 | }; 16 | int main(){ 17 | // We have our main function where we create object of class base as b/ 18 | Base b; 19 | b.func1(); 20 | b.func2(); 21 | b.func3(); // Pretty obvious as object of base class can call functions of Base 22 | 23 | Child c; // Object of class Derived created which calls functions of Base and Child class both 24 | c.func1(); 25 | c.func2(); 26 | c.func3(); 27 | c.func4(); 28 | c.func5(); 29 | // So far so good, pretty intuitive things done, now we take base class pointer p 30 | Base *p; // To this pointer we assign an object of child class 31 | p = new Child(); // It is possible for base class pointer to point to derived class object 32 | // Now we can call the functions of the class to which we made the pointer initially i.e. Base 33 | p->fun1(); 34 | p->fun2(); 35 | p->fun3(); // We can call all functions of class Base, to which we made Base *p; 36 | // As pointer is of one class and object is of another class which inherits class one. 37 | // Functions of the class of which pointer is will be called. 38 | p->fun4; // Can't be done as pointer is of base class and all functions of base class only will be called. Even if object is of derived class, functions of derived class cannot be called. 39 | } 40 | ``` 41 | 42 | Say there is a class called rectangle, and a class called cuboid which inherits class rectangle. We make a pointer to the class Rectangle and an object of class cuboid. It is like we have a cuboid object and since it inherits 2 of its parameters from the class rectangle then we can say that this object cuboid is a rectangle and this is partially correct to say so. So when we make pointer to class rectangle and make object of cuboid then this is the situation where we say cuboid object as rectangle, and since we are saying that this is a rectangle then in this case it leads to all the functions of rectangle class being called. -------------------------------------------------------------------------------- /11. Base Class Pointer Derived Class Object/02. base_class_ptr_derived_class_object.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Base 9 | { 10 | public: 11 | void fun1() { cout << "Fun1 of base." << endl; } 12 | }; 13 | 14 | class Child : public Base 15 | { 16 | public: 17 | void fun2() { cout << "Fun2 of child." << endl; } 18 | }; 19 | int main() 20 | { 21 | /* 22 | Child c; // Creating an object of child class and calling both fun1 and fun2. 23 | c.fun1(); 24 | c.fun2(); 25 | */ 26 | //------------------------------------------------------------------------------------- 27 | //Taking a base class pointer and assigning to it the address of child class object c. 28 | Child c; 29 | Base *ptr = &c; 30 | ptr->fun1(); 31 | // ptr->fun2(); // Gives error Base class has no member fun2(). 32 | // Here object is child class and ptr is of Base class so it has only functions of Base class accessible. 33 | 34 | // Trying to create a pointer to child class and pointing it to base or parent class not possible as below 35 | /* 36 | Base test_object; 37 | Child *ptr = &test_object; // Gives an error that a value of type base can't be used to initialize a value of type child*. 38 | */ 39 | return 0; 40 | } 41 | // Base class pointer pointing to the child class object can only call to the functions of base class. 42 | -------------------------------------------------------------------------------- /11. Base Class Pointer Derived Class Object/03. base_ptr_der_object.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class Rectangle 10 | { 11 | public: 12 | void area() 13 | { 14 | cout << "Area of rectangle " << endl; 15 | } 16 | }; 17 | 18 | class Cuboid : public Rectangle 19 | { 20 | public: 21 | void volume() { cout << "Volume of cuboid " << endl; } 22 | }; 23 | 24 | int main() 25 | { 26 | Cuboid c; 27 | /* Able to call both of the functions 28 | c.area(); 29 | c.volume(); 30 | */ 31 | // Creating pointer to rectangle class and to this we will assign the address of it's child class object i.e. c 32 | Rectangle *p = &c; 33 | p->area(); // Able to call the function area as it is defined in the class Rectangle. 34 | // p->volume(); // Gives error that Rectangle has no member volume() 35 | return 0; 36 | } 37 | /* 38 | Above code basically creates the object c of cuboid class but when we use pointer of Rectangle class then it means that 39 | we are addressing or will be able to access only those parts of the derived class cuboid which have been brought in from 40 | class Rectangle which is the class of pointer. So we are able to access only stuff present in Rectangle class 41 | even if we store the address of Cuboid object in the class. 42 | */ -------------------------------------------------------------------------------- /11. Base Class Pointer Derived Class Object/04. base_class_ptr.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Basic_Car 9 | { 10 | public: 11 | void start() { cout << "Starting car." << endl; } 12 | }; 13 | 14 | class Advanced_Car : public Basic_Car 15 | { 16 | public: 17 | void play_music() { cout << "Playing Music." << endl; } 18 | }; 19 | int main() 20 | { 21 | Advanced_Car a; // Object creation 22 | /*a.start(); 23 | a.play_music(); */ 24 | 25 | /* 26 | Basic_Car *ptr; // Pointer of Basic Car. 27 | ptr = &a; // Point the pointer of Basic Car class to object of advanced car which inherits basic car class. 28 | ptr->start(); // Accessible and works without any problem. 29 | // ptr->play_music(); // Gives error saying Basic car class has no 30 | */ 31 | 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /12. Polymorphism/01. function_overriding.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Parent 9 | { 10 | public: 11 | void display() 12 | { 13 | cout << "Display of parent." << endl; 14 | } 15 | }; 16 | 17 | class Child : public Parent 18 | { 19 | public: 20 | void display() 21 | { 22 | cout << "Display of child." << endl; 23 | } 24 | }; 25 | 26 | int main() 27 | { 28 | Child c; 29 | c.display(); 30 | c.Parent::display(); // To call display function of Parent 31 | return 0; 32 | } 33 | 34 | /* 35 | If we create object of Parent and call the function then function of parent will be called, 36 | if we create the function with same name in the child class and even if child inherits the 37 | parent publicly even then the function of child object will be called even though parent 38 | has the function with same name as the class child. Writing the function with same name 39 | is function overriding. Already parent class has a function and child class inherits from parent 40 | and borrows that function but is redefining the function itself, in a way as if it's their own 41 | version. 42 | 43 | In function overriding signature or prototype of the function stays same while there is a change in parameters in case 44 | of function overloading. 45 | */ -------------------------------------------------------------------------------- /12. Polymorphism/02. virtual_functions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Parent 9 | { 10 | public: 11 | virtual void display() 12 | { 13 | cout << "Display of parent." << endl; 14 | } 15 | }; 16 | 17 | class Child : public Parent 18 | { 19 | public: 20 | void display() 21 | { 22 | cout << "Display of child." << endl; 23 | } 24 | }; 25 | 26 | int main() 27 | { 28 | // Parent class pointer pointing to child object 29 | Parent *p = new Child(); 30 | // Now using base class pointer we can call functions which are present in base class. 31 | p->display(); // Parent class function is called, as pointer is of Parent therefore function also is called of Parent 32 | // Using a Parent class pointer when we call an over rided function then Parent class function is called. 33 | // To execute function of child class we do the following : we make the function of Parent as virtual 34 | } -------------------------------------------------------------------------------- /12. Polymorphism/03. virtual_functions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | 9 | class BasicCar 10 | { 11 | public: 12 | virtual void start() { cout << "BasicCar Started." << endl; } 13 | }; 14 | 15 | class AdvancedCar : public BasicCar 16 | { 17 | public: 18 | void start() { cout << "AdvancedCar Started." << endl; } 19 | }; 20 | 21 | int main() 22 | { 23 | BasicCar *ptr = new AdvancedCar(); 24 | ptr->start(); // Calling without virtual in front of Basic Car start function prints BasicCar started. 25 | // Calling with virtual in front of Basic Car start function prints AdvancedCar Started. 26 | BasicCar *ptr2 = new BasicCar(); 27 | ptr2->start(); // To print BasicCar syntax 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /12. Polymorphism/04. polymorphism.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Car 9 | { 10 | public: 11 | virtual void start() { cout << "Car started."; } 12 | virtual void stop() { cout << "Car stopped."; } 13 | }; 14 | class innova : public Car 15 | { // As innova class inherits from car so it gets functions also, as it gets start, stop functions and don't have any role. 16 | // So Innova should override those functions, and we write as above 17 | public: 18 | void start() { cout << "Innova started." << endl; } 19 | void stop() { cout << "Innova stopped." << endl; } 20 | }; 21 | 22 | class swift : public Car 23 | { 24 | public: 25 | void start() { cout << "Swift started."; } 26 | void stop() { cout << "Swift stopped."; } 27 | }; 28 | int main() 29 | { 30 | Car *c = new innova(); // Pointer of type car declared 31 | c->start(); // Call function on object car as it starts. 32 | // As object assigned is innova then innova started should be printed so we make car stop 33 | // function as virtual. 34 | c->stop(); 35 | // Make car function as virtual to make sure function of innova is activated 36 | // To the same pointer c we assign swift 37 | c = new swift(); 38 | c->start(); 39 | cout << endl; 40 | c->stop(); 41 | return 0; 42 | } 43 | 44 | /* 45 | Polymorphism : Say we have a general class car. A generalised term i.e. car. car has some functions say start,stop as 46 | public. 47 | If same statement having different function calls is case of polymorphism. 48 | */ -------------------------------------------------------------------------------- /12. Polymorphism/06. abstract_class_2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Car 9 | { 10 | public: 11 | virtual void start() = 0; // Pure Virtual Function Thus, class is abstract class. 12 | /* Object creation of abstract class is not allowed but we can make pointer of abstract class. 13 | Purpose of pure virtual function is to force the child classes to override those functions and if child doesn;t 14 | overrides then child classes become Abstract classes as well. Pure virtual function used for getting polymorphism.*/ 15 | }; 16 | class Innova : public Car 17 | { 18 | public: 19 | void start() { cout << "Innova started" << endl; } 20 | }; 21 | 22 | class Swift : public Car 23 | { 24 | public: 25 | void start() { cout << "Swift started" << endl; } 26 | }; 27 | -------------------------------------------------------------------------------- /12. Polymorphism/07. Student Exercise.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | 7 | #include 8 | #include // To set number of decimal in output of area and perimeter 9 | using namespace std; 10 | class Shape 11 | { 12 | public: 13 | virtual float area() = 0; 14 | virtual float perimeter() = 0; 15 | }; 16 | 17 | class Rectangle : public Shape 18 | { 19 | private: 20 | float length, breadth; 21 | 22 | public: 23 | Rectangle(float l = 1, float b = 1) 24 | { 25 | this->length = l; 26 | this->breadth = b; 27 | // cout << this->length << endl; 28 | // cout << this->breadth << endl; 29 | } 30 | float area() { return this->length * this->breadth; } 31 | float perimeter() { return 2 * (length + breadth); } 32 | }; 33 | 34 | class Circle : public Shape 35 | { 36 | private: 37 | float radius; 38 | 39 | public: 40 | float pi = 3.1425; 41 | Circle(float radius = 1) { this->radius = radius; } 42 | float area() { return pi * this->radius * this->radius; } 43 | float perimeter() { return 2 * pi * this->radius; } 44 | }; 45 | 46 | int main() 47 | { 48 | Shape *s = new Rectangle(10.1656, 5.54653); 49 | cout << "Area of Rectangle is : " << setprecision(4) << s->area() << endl; 50 | // In setprecision(4) means total 4 digits i.e. 56.38 and setprecision 2 would give 56 only 51 | cout << "Perimeter of Rectangle is : " << setprecision(4) << s->perimeter() << endl; 52 | 53 | s = new Circle(10); 54 | cout << "Area of Circle is : " << setprecision(4) << s->area() << endl; 55 | cout << "Perimeter of Circle is : " << setprecision(4) << s->perimeter() << endl; 56 | } -------------------------------------------------------------------------------- /13. Friend and Static Member/01. friend_function.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Test 9 | { 10 | private: 11 | int a; 12 | 13 | public: 14 | friend void fun(); // Though function doesn't belongs to this class but is a friend function 15 | // and can access and manipulate values even from outside upon object but not directly. 16 | int b; 17 | 18 | protected: 19 | int c; 20 | }; 21 | 22 | // We make a global function which tries to access and set values of all data members of Test. 23 | // Global function can do so only when we have defined fun as friend inside the class 24 | // Used for operator overloading mostly. 25 | void fun() 26 | { 27 | Test t; 28 | t.a = 15; 29 | t.b = 10; 30 | t.c = 5; 31 | } 32 | int main() 33 | { 34 | 35 | return 0; 36 | } 37 | 38 | /* 39 | Say we have a class Test as above and we have private, protected and public data members of it. 40 | 41 | */ 42 | /* 43 | /* 44 | author : Anmol Tomer 45 | email : anmol3540@gmail.com 46 | 47 | */ 48 | #include 49 | using namespace std; 50 | int main() 51 | { 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /13. Friend and Static Member/02. friend_classes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | class Your; // So we do class Your; before its declaration so compiler understands it on Line #14 10 | class My 11 | { 12 | private: 13 | int a = 10; 14 | friend Your; // When we write friend here compiler might say there is no class named Your GoTo: Line 9 15 | }; 16 | 17 | class Your 18 | { 19 | public: 20 | My m; 21 | void fun() 22 | { 23 | cout << "Value of private member of class m is : " << m.a; 24 | // Error until we give access upon object of class My using friend by making Your as friend class of object 25 | } 26 | }; 27 | 28 | /* 29 | Friend classes : Above there is a class called My and has only one data member which is private and is a. 30 | Another class called your exists which takes an object of class My and public, (has a relationship) 31 | Upon object m created in Your class publicly no data member can be accessed, that's why we make the class your as friend. 32 | 33 | To allow one class to access private members of another class upon object then we make class Your as friend of class My. 34 | 35 | This concept is useful in container classes. Your has an object of class m so Your class is container of objects of My class. 36 | So, in container classes if we want to access private or protected members then what we do is we declare them as friend 37 | inside those classes. 38 | */ 39 | int main() 40 | { 41 | Your y; 42 | y.fun(); 43 | return 0; 44 | } -------------------------------------------------------------------------------- /13. Friend and Static Member/03. static_members.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | class Test 10 | { 11 | private: 12 | int a, b; 13 | 14 | public: 15 | static int count; 16 | Test() 17 | { 18 | a = 10; 19 | b = 10; 20 | count++; // Doing count++ inside constructor 21 | } 22 | 23 | // Static function 24 | static int getCount() 25 | { 26 | // a++; // Not allowed as static function can access only static members 27 | // Static member function also belongs to a class. 28 | 29 | return count; 30 | } 31 | }; 32 | 33 | int Test::count = 0; // As we want accessible inside Test only, hence we do scope resolution operator :: 34 | // So 2 times declaration is needed for static variables. As we make global variable static accessible to objects of the class. 35 | 36 | int main() 37 | { 38 | cout << Test::getCount(); 39 | Test t1; // Constructor called and initializes object with 10 and 10. count++ makes count to 1 40 | cout << t1.getCount(); 41 | Test t2; // count++ makes count to 2 42 | cout << t2.getCount(); 43 | cout << t1.count; // Prints 2 44 | cout << t2.count; // Prints 2 45 | cout << Test::count; // As static variable count is public . 46 | // Static data members can be accessed using objects as well as class name if static members are public. 47 | 48 | // We have created 2 object of same class and every object will have their own a and b. 49 | } 50 | 51 | /*To understand static, we will create one variable in public and we will do count++ inside constructor 52 | How this works ? When we create an object of test as t1 there are a, b and count members. 53 | On creating an object of t2 there are a,b and count as well. Count is shared by both t1 and t2. 54 | What we want to say is that on a given memory is allocted to static members once only and both objects above 55 | share the same memory of count static member. Thus, static variable occupies memory only once. 56 | Static variables or static data members belongs to a class and not to an object. Objects can share it. 57 | There is only one copy of static members and all objects share it. 58 | t1 and t2 are having their own a and b but shared count in code above. 59 | When there is a static member inside the class then we are supposed to declare it outside the class as well, again but 60 | as we want it accessible only inside the test that is why we do scope resolution wrt test. 61 | 62 | Like static members static functions can also be accessed using the class name with scope resolution operator. 63 | 64 | Conclusion : 65 | 1. Class can have static data members as well. 66 | 2. There will be only one instance which leads to memory being allocated only once. 67 | 3. All objects share that data member. 68 | 4. We can have static member functions as well to access the static members we declared as public 69 | inside the class. 70 | 5. Static member function can only access static data members. 71 | 6. 2 times you have to declare static data members. 72 | 7. Static members can be accessed by using the object or the class with scope resolution operator. 73 | 8. If we make data member as private then we need function else we do not. 74 | 75 | */ -------------------------------------------------------------------------------- /13. Friend and Static Member/04. static_example.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | class Test 10 | { 11 | public: 12 | int a; 13 | static int count; 14 | 15 | Test() 16 | { 17 | a = 10; 18 | count++; 19 | } 20 | static int getCount() 21 | { 22 | return count; 23 | } 24 | }; 25 | 26 | int Test::count = 0; 27 | 28 | int main() 29 | { 30 | Test t1, t2; 31 | cout << t1.count << endl; 32 | cout << t2.count << endl; 33 | t1.count = 25; // Change value of t1 count and print value of t2 count yet it is same as t1.count 34 | cout << t2.count << endl; 35 | cout << Test::getCount() << endl; 36 | } 37 | // Static function can be called just by class name and we can even use these over a object too. 38 | // Static members are usually useful for static members of a class and belong to a class not object. -------------------------------------------------------------------------------- /13. Friend and Static Member/05. static_members_example.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | 7 | #include 8 | using namespace std; 9 | 10 | // Example of students in a school and their static admission number as Roll No. 11 | 12 | class Student 13 | { 14 | public: 15 | int roll; 16 | string name; 17 | 18 | static int addNo; 19 | Student(string name) 20 | { 21 | addNo++; 22 | roll = addNo; 23 | this->name = name; 24 | } 25 | void display() 26 | { 27 | cout << "Name : " << name << endl; 28 | cout << "Roll No. : " << roll << endl; 29 | } 30 | }; 31 | 32 | int Student::addNo = 0; 33 | 34 | int main() 35 | { 36 | Student s1("Peter"); 37 | Student s2("John"); 38 | Student s3("Cosmic"); 39 | Student s4("Matthew"); 40 | Student s5("Eric"); 41 | Student s6("Deborah"); 42 | 43 | s1.display(); 44 | s3.display(); 45 | cout << "Number of Admissions : " << Student::addNo; 46 | } 47 | 48 | // Example of Innova and Price of all objects remaining static 49 | /*class Innova 50 | { 51 | public: 52 | static int price; 53 | static int getPrice() 54 | { 55 | return price; 56 | } 57 | }; 58 | 59 | int Innova::price = 20; 60 | 61 | int main() 62 | { 63 | Innova i1, i2, i3; 64 | cout << i1.price << endl; 65 | cout << i3.price << endl; 66 | 67 | cout << Innova::price << endl; 68 | } 69 | */ -------------------------------------------------------------------------------- /13. Friend and Static Member/06. inner_nested_class.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | class Outer 9 | { 10 | public: 11 | int a = 10; 12 | static int b; 13 | 14 | void func() 15 | { 16 | // Blank function 17 | i.show(); 18 | cout << i.x; // Accessible all the public members in inner class from function of outer class 19 | } 20 | 21 | class Inner 22 | { 23 | public: 24 | int x = 25; 25 | void show() 26 | { 27 | cout << "Show of inner works..!"; 28 | // cout< 7 | using namespace std; 8 | int main() 9 | { 10 | 11 | return 0; 12 | } 13 | 14 | /* 15 | Exception handling is a feature of OOP also exists in JAVA. 16 | Exception meaning : 17 | There are usually 3 kinds of errors that occur in programming 18 | 1. Syntax Error -> Programmer mistypes or skips writing something or writes it in an improper way then it leads to 19 | syntax error. This is usually caught by compiler on the step where we build the executable file. 20 | Examples of these types of error are (i) Variable declared but not used, used but not initialized,missing semicolon, 21 | if-else ladder not made properly , these mostly occurs not due to wrong logic but lack of knowledge of syntax. 22 | 23 | 2. Logical Error -> Want to do task A but what happens is something unexpected, no errors in syntax but in expected 24 | output. These types of errors are difficult to remove as you have to think. Compiler won't help you but Pen and Paper 25 | will help for sure along with debugger. 26 | 27 | 3. Run-time Error -> Occurs when user is using an application and if user mishandles the app then app may 28 | cause error during the runtime of program. There were no errors during development phase but there exists error during 29 | runtime. 30 | e.g.(i) Bad Input -> Suppose user needs to give int but is entering a string then it will mess up the program for sure. 31 | (ii) Internet Connectivity. 32 | (iii) Deletion of crucial files required for proper functioning of program. 33 | (iv) Program dependent on a Printer or other hardware resource but that is not connected. 34 | 35 | Program crashes abruptly during runtime errors. And it is users who are responsible for runtime error. 36 | 37 | Exceptions are referred to as those inputs or cases upon entering of which program will give runtime error. 38 | And way to address exceptions is to ask user for input until correct input is given. 39 | Program gives meaningfull message to user so that users can remove wrong inputs themselves. 40 | 41 | Thus, lack or inappropriate availability of resources causes Runtime errors which are external factors to the program. 42 | 43 | What can be done in case of these run time errors ? You should raise some error or notify the user on receiving the error. This helps to guide the user so that user can troubleshoot the error. 44 | */ -------------------------------------------------------------------------------- /14. Exception Handling/02. exception_handling.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int main() 9 | { 10 | int x = 10, y = 0, z; 11 | try 12 | { 13 | if (y == 0) 14 | throw 0; 15 | z = x / y; 16 | cout << z << endl; 17 | } 18 | catch (int e) 19 | { 20 | cout << "Division by zero...!! Error Code: " << e << endl; 21 | } 22 | cout << "Outside try catch"; 23 | return 0; 24 | } 25 | /* 26 | Construct: 27 | 28 | try 29 | { 30 | // conditions 31 | } 32 | 33 | catch(data_type var_name) 34 | { 35 | 36 | } 37 | 38 | Explanation: Inside try block if there is any error it will jump to the catch block and execute the statements specified there. 39 | If there are no errors in try block, catch block won't be executed at all. If no error run the entire try block, else go to catch block. 40 | 41 | C++ compiler does not have any built-in mechanism for throwing the exception, rather we have to check for some conditions which may lead to error and based on that we have to throw exceptions. Java writes the code for throwing exception but C++ doesn't do that. 42 | 43 | It doesn't matter what is it that you are throwing just throw something and same datatype should be put in catch block, and display your message inside the catch block. 44 | Throw catch is just so that we can have a link between the point error occurs and connecting it to the code that tells what to show as error. You can do error code as well. 45 | 46 | Or giving error codes can be helpful say in documentation you can give user a manual where you tell the user that this error code is thrown for this particular run time error. 47 | */ -------------------------------------------------------------------------------- /14. Exception Handling/03. exception_handling_in_functions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | author : Anmol Tomer 3 | email : anmol3540@gmail.com 4 | 5 | */ 6 | #include 7 | using namespace std; 8 | int division(int x, int y) 9 | { 10 | // Inside the function check for error condition throw something for catch block and return the result if error condition is not satisfied. 11 | if (y == 0) 12 | throw 1; 13 | return x / y; 14 | } 15 | int main() 16 | { 17 | int a = 10, b = 0, c; 18 | try 19 | { 20 | c = division(a, b); // Pass division to the function. 21 | cout << c; 22 | } 23 | catch (int e) 24 | { 25 | cout << "Division by zero. Error code : " << e << endl; 26 | } 27 | cout << "\nOutside try catch.\n"; 28 | return 0; 29 | } 30 | 31 | /* 32 | Actual purpose of try, catch throw we see above. 33 | When we call a function that function returns a result, and in case of function not being able to return the result 34 | then function should be able to inform the calling function that there is some problem. We want functions to be able to communicate with each other. 35 | So when function is called it should either return the result or it should tell about error. 36 | So we can say that throw catch try is used for comms between functions. If we want 2 functions main and division whenever 37 | main calls division to communicate whether result is returned or if exception is there we use try catch thingy. 38 | 39 | That's why try catch is useful in functions with help of throw, otherwise we could just use 40 | */ -------------------------------------------------------------------------------- /14. Exception Handling/04_throw.md: -------------------------------------------------------------------------------- 1 | ## Notes on throw 2 | 3 | - In the syntax below: 4 | 5 | ```cpp 6 | int division(int x,iny y) 7 | { 8 | if(y == 0) 9 | throw something; 10 | return x/y; 11 | } 12 | ``` 13 | 14 | - In the syntax above we can throw double,float,int,char and even string with message. 15 | 16 | - We can write our own class, and we can throw an object of our class say MyException as well. If we are throwing our own class exception, it would be better to extend it from built-in class of C++ called exception, and we can inherit our class form that. 17 | 18 | ```cpp 19 | class MyException 20 | { 21 | // something 22 | }; 23 | int division(int x,iny y) 24 | { 25 | if(y == 0) 26 | throw MyException; 27 | return x/y; 28 | } 29 | ``` 30 | 31 | - Specifying empty throw( ) in front of your function means that function doesn't throws any exception. 32 | 33 | ```cpp 34 | int division (int x, int y) throw( ) // means no exception thrown. 35 | { 36 | return(x/y); 37 | } 38 | ``` -------------------------------------------------------------------------------- /14. Exception Handling/05_throw.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // --------------------------------------------VERSION 5 : Class MyException: Inherit from exception----------------------------------------- 4 | 5 | class MyException : exception 6 | { 7 | }; 8 | 9 | int division(int a, int b) throw(MyException) 10 | { 11 | if (b == 0) 12 | throw MyException(); 13 | return a / b; 14 | } 15 | 16 | int main() 17 | { 18 | int x = 10, y = 0, z; 19 | try 20 | { 21 | z = division(x, y); 22 | cout << z << endl; 23 | } 24 | catch (MyException e) 25 | { 26 | cout << "Division by zero" << '\n'; 27 | } 28 | } 29 | // --------------------------------------------VERSION 4 : Class MyException: Inherit from exception----------------------------------------- 30 | 31 | // --------------------------------------------VERSION 4 : Class MyException----------------------------------------- 32 | // class MyException 33 | // { 34 | // }; 35 | // int main() 36 | // { 37 | // int x = 10, y = 0, z; 38 | // try 39 | // { 40 | // if (y == 0) 41 | // throw MyException(); 42 | // z = x / y; 43 | // cout << z << endl; 44 | // } 45 | // catch (MyException e) 46 | // { 47 | // cout << "Division by zero." << '\n'; 48 | // } 49 | 50 | // cout << "Out of Try - Throw - Catch.\n"; 51 | // } 52 | // --------------------------------------------VERSION 4 : Class MyException----------------------------------------- 53 | 54 | // -------------------------------------------- VERSION 3: Throw STRING----------------------------------------- 55 | // { 56 | // int x = 10, y = 0, z; 57 | // try 58 | // { 59 | // if (y == 0) 60 | // throw string("Division by zero."); 61 | // z = x / y; 62 | // cout << z << endl; 63 | // } 64 | // catch (string e) 65 | // { 66 | // cout << e << '\n'; 67 | // } 68 | 69 | // cout << "Out of Try - Throw - Catch.\n"; 70 | // } 71 | // -------------------------------------------- VERSION 3: Throw STRING----------------------------------------- 72 | 73 | // -------------------------------------------- VERSION 2: Throw DOUBLE----------------------------------------- 74 | // { 75 | // int x = 10, y = 0, z; 76 | // try 77 | // { 78 | // if (y == 0) 79 | // throw 1.5; 80 | // z = x / y; 81 | // cout << z << endl; 82 | // } 83 | // catch (double e) 84 | // { 85 | // cout << "Division by zero ERR Code: " << e << '\n'; 86 | // } 87 | 88 | // cout << "Out of Try - Throw - Catch.\n"; 89 | // } 90 | // -------------------------------------------- VERSION 2: Throw DOUBLE----------------------------------------- 91 | 92 | // -------------------------------------------- VERSION 1: Throw INT----------------------------------------- 93 | // { 94 | // int x = 10, y = 0, z; 95 | // try 96 | // { 97 | // if (y == 0) 98 | // throw 1; 99 | // z = x / y; 100 | // cout << z << endl; 101 | // } 102 | // catch (int e) 103 | // { 104 | // cout << "Division by zero ERR Code: " << e << '\n'; 105 | // } 106 | 107 | // cout << "Out of Try - Throw - Catch.\n"; 108 | // } 109 | // -------------------------------------------- VERSION 1: Throw INT----------------------------------------- -------------------------------------------------------------------------------- /14. Exception Handling/06_catch_multiple.cpp: -------------------------------------------------------------------------------- 1 | // We can have catch block of multiple types and for exception we do not know which type it is of for that we do catch(...) this is called catch all. 2 | // exceptions are checked for in the order of catch. If you declare catch all in the beginning all exceptions will go to catch all in that case. 3 | // We can have try block inside try block i.e. nested try as well. Nesting of try and catch can be done as well. 4 | // If we have 2 classes, parent and child class, in that case if we have a try block and inside that there is a possibility of both the exceptions, so we will catch both the exceptions, we will have a catch each for parent and child class. First we specify catch for child class and after that catch for parent class as if we define exception of parent class first it is capable of handline and catching exception of child class as well. 5 | 6 | #include 7 | 8 | using namespace std; 9 | 10 | int main() 11 | { 12 | try 13 | { 14 | throw 'a'; 15 | throw 1; // We can have multiple catch blocks for every data type. 16 | throw 1.5; // Will give error of uncaught exception of type double found if you have catch with (int e) 17 | } 18 | 19 | catch (int e) 20 | { 21 | cout << "Int catch" << endl; 22 | } 23 | catch (double e) 24 | { 25 | cout << "Double catch." << endl; 26 | } 27 | catch (...) 28 | { 29 | cout << "Catch all." << endl; 30 | } 31 | } -------------------------------------------------------------------------------- /14. Exception Handling/07_stack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class StackOverFlow : exception 6 | { 7 | }; 8 | class StackUnderFlow : exception 9 | { 10 | }; 11 | 12 | class Stack 13 | { 14 | private: 15 | int *stk; 16 | int top = -1; 17 | int size; 18 | 19 | public: 20 | Stack(int sz) 21 | { 22 | this->size = sz; 23 | stk = new int[size]; 24 | } 25 | 26 | void push(int x) 27 | { 28 | try 29 | { 30 | if (top == size - 1) 31 | throw StackOverFlow(); 32 | top++; 33 | stk[top] = x; 34 | cout << "Added to the stack: " << x << endl; 35 | } 36 | catch (StackOverFlow e) 37 | { 38 | cout << "Stack Overflow you have exceeded the size of stack.\n"; 39 | } 40 | } 41 | 42 | int pop() 43 | { 44 | try 45 | { 46 | if (top == -1) 47 | throw StackUnderFlow(); 48 | cout << "Popped from stack: " << stk[top] << endl; 49 | return stk[top--]; 50 | } 51 | catch (StackUnderFlow f) 52 | { 53 | cout << "You are trying to pop from an empty stack.\n"; 54 | } 55 | } 56 | }; 57 | 58 | int main() 59 | { 60 | Stack s(5); 61 | s.pop(); 62 | s.push(2); 63 | s.push(3); 64 | s.push(4); 65 | s.push(10); 66 | s.push(15); 67 | s.push(45); 68 | s.pop(); 69 | s.pop(); 70 | } -------------------------------------------------------------------------------- /15. Template Functions and Classes/README.md: -------------------------------------------------------------------------------- 1 | ## Templates 2 | 3 | - Templates are used for generic programming. We can write the code which can work for any type of data. If we want the following int based function to work for any data type: 4 | 5 | ```cpp 6 | int maximum(int x, int y){ 7 | return x > y? x:y; 8 | } 9 | ``` 10 | 11 | - We can use template class to make the above function work for any type of data, we define template class T. 12 | 13 | ```cpp 14 | template 15 | { 16 | T maximum(T x, T y) 17 | { 18 | return x>y?x:y; 19 | } 20 | } 21 | ``` 22 | 23 | - Taking example of a multiple parameters to template classes. 24 | 25 | ```cpp 26 | template 27 | void add(T x, R y) 28 | { 29 | cout << x+y ; // Allows us to do addition where we pass int and float to the function. 30 | } 31 | ``` 32 | 33 | - **Template Classes:** We take a look at example class Stack. We take an array for implementation of stack, we have a top pointer to point to a particular index. This stack works only for integer and is not able to handle float or any other data type. Instead of writing separate classes for different data types, we can write single class for all data types that will work for float,char and all other data types. To do so we can make the **class as template**. 34 | 35 | ```cpp 36 | class stack 37 | { 38 | private: 39 | int s[10]; 40 | int top; 41 | public: 42 | void push(int x) 43 | int pop(); 44 | }; 45 | ``` 46 | 47 | - **Class as Template:** We define a class of type template we use the following method: 48 | 49 | ```cpp 50 | template 51 | class stack 52 | { 53 | private: 54 | T s[10]; 55 | int top; 56 | 57 | public: 58 | void push(T x); 59 | T pop(); 60 | }; 61 | // Outside the class we again have to write T we used for template above. 62 | 63 | template 64 | void stack::push(T x) 65 | { 66 | // Code for push 67 | } 68 | 69 | template 70 | 71 | void stack:pop() 72 | { 73 | // Code for pop 74 | } 75 | 76 | // To create object of stack class we do 77 | 78 | stack D; // Int stack 79 | stack F; // Float stack 80 | ``` -------------------------------------------------------------------------------- /15. Template Functions and Classes/stack_int.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Stack 6 | { 7 | private: 8 | int *stk; 9 | int top; 10 | int size; 11 | 12 | public: 13 | Stack(int size) // Constructor 14 | { 15 | this->size = size; 16 | top = -1; 17 | this->stk = new int[size]; 18 | } 19 | 20 | void push(int value); // Functions defined outside using scope resolution :: operator. 21 | int pop(); 22 | }; 23 | 24 | void Stack::push(int value) 25 | { 26 | if (top == size - 1) 27 | { 28 | cout << "Stack is full.\n"; 29 | } 30 | else 31 | { 32 | top++; 33 | stk[top] = value; 34 | cout << "Added to the stack: " << value << endl; 35 | } 36 | } 37 | 38 | int Stack::pop() 39 | { 40 | int x = 0; 41 | if (top == -1) 42 | cout << "Stack is empty.\n"; 43 | else 44 | { 45 | x = stk[top]; 46 | top--; 47 | cout << "Popped: " << x << "\n"; 48 | } 49 | return x; 50 | } 51 | 52 | int main() 53 | { 54 | Stack s(4); 55 | s.push(4); 56 | s.push(9); 57 | s.push(8); 58 | s.push(5); 59 | s.push(7); 60 | s.pop(); 61 | s.pop(); 62 | s.pop(); 63 | s.pop(); 64 | s.pop(); 65 | } -------------------------------------------------------------------------------- /15. Template Functions and Classes/template_stack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | class Stack 7 | { 8 | private: 9 | T *stk; 10 | int top; 11 | int size; 12 | 13 | public: 14 | Stack(int size) // Constructor 15 | { 16 | this->size = size; 17 | top = -1; 18 | this->stk = new T[size]; 19 | } 20 | 21 | void push(T value); // Functions defined outside using scope resolution :: operator. 22 | T pop(); 23 | }; 24 | 25 | template 26 | void Stack::push(T value) 27 | { 28 | if (top == size - 1) 29 | { 30 | cout << "Stack is full.\n"; 31 | } 32 | else 33 | { 34 | top++; 35 | stk[top] = value; 36 | cout << "Added to the stack: " << value << endl; 37 | } 38 | } 39 | 40 | template 41 | T Stack::pop() 42 | { 43 | T x = 0; 44 | if (top == -1) 45 | cout << "Stack is empty.\n"; 46 | else 47 | { 48 | x = stk[top]; 49 | top--; 50 | cout << "Popped: " << x << "\n"; 51 | } 52 | return x; 53 | } 54 | 55 | int main() 56 | { 57 | 58 | Stack s(4); 59 | s.push("John"); 60 | s.push("Elliott"); 61 | s.push("Darlene"); 62 | s.push("Tyler"); 63 | // s.push("Angela"); 64 | s.pop(); 65 | s.pop(); 66 | s.pop(); 67 | s.pop(); 68 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/const0.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | const int x = 10; 8 | cout << x << endl; 9 | const int *ptrX = &x; 10 | cout << *ptrX << endl; 11 | 12 | // Pointer to int 13 | int y = 5; 14 | int *ptrY = &y; 15 | ++*ptrY; 16 | cout << *ptrY << endl; 17 | 18 | // const ptr to int 19 | int z = 5; 20 | const int *ptrZ = &z; 21 | // ++*ptrZ; // --> Not allowed. Gives error. 22 | cout << *ptrZ << endl; 23 | // *ptrZ = &y; // Not allowed --> Gives error. 24 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/const1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | int x = 10; 8 | int *ptr = &x; 9 | cout << "*ptr = " << *ptr << endl; 10 | cout << ++*ptr << endl; 11 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/const2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | const int x = 10; 8 | const int *ptr = &x; // Pointer of type integer constant. 9 | cout << "*ptr = " << *ptr << endl; 10 | // cout << ++*ptr << endl; // ERROR 11 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/const3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | int x = 10; 8 | const int *ptr = &x; // Pointer of type integer constant, even if x is not const, it means we can't change x using ptr pointer. 9 | cout << "*ptr = " << *ptr << endl; 10 | // cout << ++*ptr << endl; // ERROR 11 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/const4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | int x = 10; 8 | const int *ptr = &x; // Pointer of type integer constant, even if x is not const, it means we can't change x using ptr pointer. 9 | cout << "*ptr when *ptr = &x ==> " << *ptr << endl; 10 | int y = 20; 11 | ptr = &y; 12 | cout << "*ptr when *ptr = &y ==> " << *ptr << endl; 13 | // Can modify on which variable ptr points to but can't modify var value just like before. 14 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/const5.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | int x = 10; 8 | int *const ptr = &x; // ptr constant of type integer pointer. Now ptr is a constant and is an integer pointer, so it can't point to any other variable. Though it can definitely 9 | cout << "*ptr when *ptr = &x ==> " << *ptr << endl; 10 | cout << "++*ptr = " << ++*ptr << endl; 11 | int y = 20; 12 | // ptr = &y; 13 | // cout << "*ptr when *ptr = &y ==> " << *ptr << endl; 14 | // Can modify on which variable ptr points to but can't modify var value just like before. 15 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/const6.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | int x = 10; 8 | const int *const ptr = &x; // ptr is a constant pointer to an integer constant. 9 | cout << "*ptr when *ptr = &x ==> " << *ptr << endl; 10 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/const7.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Demo 6 | { 7 | public: 8 | int x = 10; 9 | int y = 20; 10 | 11 | void Display() // writing const after display function will give error on the step where we do x++ because we declare the function as constant. 12 | { 13 | // x++; // Due to const above we have made this function read only and prohibiting this from making any kind of modifications to the class members. 14 | cout << "x = " << x << "\ny = " << y << endl; 15 | } 16 | }; 17 | 18 | int main() 19 | { 20 | Demo d; 21 | d.Display(); 22 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/const8.cpp: -------------------------------------------------------------------------------- 1 | // constant in functions 2 | #include 3 | 4 | using namespace std; 5 | 6 | // void fun(int &a, int &b) // Passing parameters by reference. Allows us to modify value of a. 7 | void fun(const int &a, int &b) // Passing parameters by reference. 8 | { 9 | cout << "x = " << a << "\ny = " << b << endl; 10 | // a++; // Since reference of a is passed as const int we cannot modify value of a only read it. 11 | } 12 | 13 | int main() 14 | { 15 | int x = 10; 16 | int y = 20; 17 | fun(x, y); // Call by reference is used when we want function to modify the values of variables that are being passed to it. 18 | cout << "After function call \n"; 19 | cout << "x = " << x << "\ny = " << y << endl; 20 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/macro0.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | // ________________________DEFINE MACROS_______________________________________________________________ 6 | 7 | #define PI 3.1425 8 | // #define PI 3 // Gives error that PI macro already defined. 9 | 10 | #ifndef PI2 11 | #define PI2 3.14 12 | #endif 13 | #define max(x, y) (x > y ? x : y) 14 | #define MSG(x) #x 15 | int main() 16 | { 17 | cout << PI << endl; 18 | cout << PI2 << endl; 19 | cout << "Max of PI and and PI2 is :" << max(PI, PI2) << endl; 20 | cout << MSG(hello) << endl; // Auto convert to string 21 | return 0; 22 | } -------------------------------------------------------------------------------- /16. Constants Preprocessors or Directives and Namespaces/namespace0.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | namespace First //encapsulating within namespaces 4 | { 5 | void func() 6 | { 7 | cout << "First"; 8 | } 9 | } // namespace First 10 | 11 | namespace Second 12 | { 13 | void func() 14 | { 15 | cout << "Second"; 16 | } 17 | } // namespace Second 18 | int main() 19 | { 20 | First::func(); 21 | cout << "\n"; 22 | return 0; 23 | } -------------------------------------------------------------------------------- /17. Destructors and Virtual Destructors/README.md: -------------------------------------------------------------------------------- 1 | ## Destructors 2 | 3 | - We have already looked at constructors here we understand destructors with the help of following class called `Test` 4 | 5 | ```cpp 6 | class Test 7 | { 8 | public: 9 | Test() 10 | { 11 | cout << "Test created"; 12 | } 13 | ~Test() 14 | { 15 | cout << "Test destroyed"; 16 | } 17 | } 18 | 19 | main() 20 | { 21 | Test *p = new Test(); // Constructor is called 22 | 23 | delete P; // Destructor is called. 24 | } 25 | ``` 26 | 27 | - `~Test()` is the destructor. Destructor is called when object is destroyed. Constructor is used for initialization purpose and is used to allocate resources. So, makes sense to come to conclusion that destructor is used **for deallocating resources**. External resources such as heap memory,file, network connection. Everything class acquires in constructor, class should release that in destructor. 28 | 29 | - **Some Rules:** 30 | - Can we overload a constructor ? **Yes** 31 | - Can we have multiple destructors? **No** 32 | - Can a constructor return anything ? **No** 33 | - Can a destructor return anything ? **No** 34 | 35 | ## Destructors Inheritance : Virtual Destructor 36 | 37 | ```cpp 38 | class Base 39 | { 40 | public: 41 | Base() 42 | { 43 | cout << "Constructor of Base"; 44 | } 45 | ~Base() 46 | { 47 | cout << "Destructor of Base"; 48 | } 49 | }; 50 | class Derived:public Base 51 | { 52 | public: 53 | Derived() 54 | { 55 | cout << "Constructor of Derived"; 56 | } 57 | ~Derived() 58 | { 59 | cout << "Destructor of Derived"; 60 | } 61 | }; 62 | 63 | int main() 64 | { 65 | Derived d; // Will print constructor of Base followed by Constructor of Derived 66 | } 67 | ``` 68 | 69 | - When object gets deleted first Destructor of Derived will be called and after that only Destructor of Base will be called. Constructors are called from top to bottom or descending order and destructors are called from bottom to top or smallest class towards the derived class i.e. ascending order. 70 | 71 | ## Problem with Destructors: 72 | 73 | - Say in main class you have a pointer, p to **Base** class but using that pointer we make object of **Derived** class in foll. manner. 74 | 75 | ```cpp 76 | main() 77 | { 78 | Base *p; 79 | p = new Derived(); 80 | ... 81 | ... 82 | ... 83 | delete P; // Deletes derived class object. 84 | } 85 | ``` 86 | 87 | - Destructor of derived and after that destructor of base class should be called, but here we have a pointer of Base class and the object of Derived class, so destructor of only Derived class will be called. But Base class destructor should also be called. 88 | 89 | - When we have Base class pointer and we make Derived class object to call the Base class destructor we write virtual in front of Base class destructor `~Base()`, this is the reason we have virtual destructors. 90 | 91 | - So, in inheritance if we want base class destructors to also be executed when derived class destructors are called we make it virtual. -------------------------------------------------------------------------------- /17. Destructors and Virtual Destructors/destructor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Demo 6 | { 7 | int *p; 8 | 9 | public: 10 | Demo() 11 | { 12 | p = new int[10]; 13 | cout << "Constructor of Demo" << endl; 14 | } 15 | ~Demo() 16 | { 17 | delete[] p; // To prevent deleting of class but memory of array not deleted from heap. Specify all resources to remove here. 18 | cout << "Destructor of Demo" << endl; 19 | } 20 | }; 21 | 22 | void func() 23 | { 24 | // Demo d; // Constructor and Destructor both are called. 25 | Demo *p = new Demo(); // Only constructor is called, when we create an object dynamically in the heap. 26 | delete p; // When dealing with dynamic objects via pointers delete them by doing `delete p` 27 | } 28 | 29 | int main() 30 | { 31 | func(); 32 | } -------------------------------------------------------------------------------- /17. Destructors and Virtual Destructors/virtual_destructor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Base 6 | { 7 | public: 8 | Base() { cout << "Constructor of Base\n"; } 9 | // ~Base() 10 | virtual ~Base() // Allows us to call destructor of derived class when pointer of Base class is used to create object of derived class. 11 | { 12 | cout << "Destructor of Base" << endl; 13 | } 14 | }; 15 | 16 | class Derived : public Base 17 | { 18 | public: 19 | Derived() { cout << "Constructor of Derived\n"; } 20 | ~Derived() 21 | { 22 | cout << "Destructor of Derived" << endl; 23 | } 24 | }; 25 | 26 | void fun() 27 | { 28 | // Derived d; 29 | Base *p = new Derived(); // From base class pointer create Derived class object in heap 30 | delete p; // Delete object from heap. This will run only the destructor of derived class if base destructor is not made virtual. 31 | } 32 | 33 | int main() 34 | { 35 | fun(); 36 | } -------------------------------------------------------------------------------- /18. IO Streams/README.md: -------------------------------------------------------------------------------- 1 | ## Streams 2 | 3 | - Stream is a flow of data or flow of characters, streams are used for accessing the data from outside the program. From external sources or destination. We can have data from external source to program or vice-versa. 4 | 5 | - Program can get data from keyboard, send data to monitor, read and write data to a file or from a network. There are various sources for program to receive and send data. There are Input Output streams called I/O. There are built-in classes present in C++ to access I/O streams that we can make use of. 6 | 7 | - Name of class is **ios** i.e. input output stream. From this we have `istream` class for input stream and `ostream` class for output stream. For **accessing files** there are classes available called `ifstream` input file stream and `ofstream` output file stream. 8 | 9 | - For input stream from the keyboard, there is already an object present in iostream header file called `cin` and cout object of ostream class used to output to a device your data. 10 | 11 | ## File Handling 12 | 13 | ```cpp 14 | #include 15 | #include 16 | int main() 17 | { 18 | ofstream outfile("file.txt",ios::app); // Associate outfile object with the file passed to it. What we write to outfile object gets associated with the file. 19 | // To insert 20 | outfile << "Hello"< 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | ifstream infile; 8 | infile.open("write0.txt"); // Modes ios::in for reading and ios::out for writing, ifstream for reading only here. 9 | // File must exist, new file won't be created when working with ifstream object. 10 | 11 | //Method 1 to Check if file is open 12 | /*if (!infile) 13 | { 14 | cout << "File not present.\n"; 15 | }*/ 16 | 17 | // Method 2 to check if file is open 18 | if (!infile.is_open()) 19 | { 20 | cout << "File not present.\n"; 21 | } 22 | else 23 | { 24 | string str; 25 | int x; 26 | infile >> str; 27 | infile >> x; 28 | cout << str << " " << x << endl; 29 | // To check end of the file 30 | } 31 | if (infile.eof()) 32 | { 33 | infile.close(); 34 | cout << "End of file reached! Closing file now." << endl; 35 | } 36 | } -------------------------------------------------------------------------------- /18. IO Streams/serialization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Student 6 | { 7 | public: 8 | string name; 9 | int roll; 10 | string branch; 11 | 12 | friend ofstream &operator<<(ofstream &ofs, Student &s); // Use friend function to override insertion or extraction operator. 13 | friend ifstream &operator>>(ifstream &ifs, Student &s); 14 | }; 15 | 16 | ofstream &operator<<(ofstream &ofs, Student &s) 17 | { 18 | ofs << s.name << endl; 19 | ofs << s.roll << endl; 20 | ofs << s.branch << endl; 21 | return ofs; 22 | } 23 | 24 | ifstream &operator>>(ifstream &ifs, Student &s) 25 | { 26 | ifs >> s.name >> s.roll >> s.branch; 27 | 28 | return ifs; 29 | } 30 | 31 | int main() 32 | { 33 | Student s1; 34 | s1.name = "Tomer"; 35 | s1.roll = 10; 36 | s1.branch = "ECM"; 37 | ofstream ofs("serialization.txt"); 38 | 39 | // We can store in the following manner 40 | /* 41 | ofs << s1.name << endl; 42 | ofs << s1.roll << endl; 43 | ofs << s1.branch << endl; 44 | */ 45 | 46 | // We can instead store the object so that all members can be stored. For this we overload the operator of ofstream in student class. 47 | ofs << s1; 48 | 49 | ifstream ifs("serialization.txt"); 50 | ifs >> s1; // Overloading of ifs input file stream. 51 | cout << "Name " << s1.name << endl; // Open file and read data directly by overloading of operators. 52 | cout << "Roll No " << s1.roll << endl; 53 | cout << "Branch " << s1.branch << endl; 54 | ifs.close(); 55 | ofs.close(); 56 | } -------------------------------------------------------------------------------- /18. IO Streams/serialization.txt: -------------------------------------------------------------------------------- 1 | Tomer 2 | 10 3 | ECM 4 | -------------------------------------------------------------------------------- /18. IO Streams/write0.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int main() 7 | { 8 | ofstream obj("write0.txt", ios::app); 9 | obj << "John" << endl; 10 | obj << 25 << endl; 11 | obj << "ECM" << endl; 12 | obj.close(); 13 | } -------------------------------------------------------------------------------- /18. IO Streams/write0.txt: -------------------------------------------------------------------------------- 1 | John 2 | 25 3 | ECM 4 | -------------------------------------------------------------------------------- /19. STL/README.md: -------------------------------------------------------------------------------- 1 | ## Data Structures 2 | 3 | - To store the collection of values we need data structures. Arrangement of data for efficient utilization is what the study of Data Structures is all about. Efficiency is measured on 2 parameters time and space. CPP provides arrays, but problem is that it is of fixed size which can't be modified as per the need. 4 | 5 | - Another Data Structure is Linked List, Size of LL can grow and reduce as per the numbers being inserted or deleted. Easy to create new nodes in a LL. There are doubly as well as circular linked lists too. 6 | 7 | - Some of the other Data Structures are: Stack, Queue, Dequeue, Priority Queue, Map, Set, Graphs etc. So, as a programmer do we have to define all these data structures before using them in our program ? No, we don't have to do that. C++ provides built-in library of classes for all these data structures and that is collection of classes called as STL. 8 | 9 | - There are some collection of header files having many classes in them and that collection is called as STL. There is class available for LL, arrays, stack etc. 10 | 11 | ## Standard Template Library (STL) 12 | 13 | - STL has **algorithms**, **containers** and **iterators**. There are built-in algorithms of functions that are meant to manage the containers. Containers contain collection of data. There are iterators to iterate through the collection of values. To access the containers we have iterators available. Algorithms contain, search(), sort(), binary-search(),concat(),copy(),union(), reverse(),merge(),heap() are some of the functions that are available to be called on containers 14 | 15 | - Containers: These are template classes, can work for any kind of data. 16 | 1. **vector**: Array that can grow and reduce as per the input. Has functions like **push_back()**, **pop_back()**,**insert()**,**remove()**,**size()** and **empty()**. 17 | 18 | 2. **list**: **Doubly linked list**. Has functions same as vector but additional ones like **push_front()**,**pop_front()**,front(), back() etc. 19 | 20 | 3. **forward_list**: **Single linked list**, introduced in C11. As double linked list needs space for pointer to next and previous node. 21 | 22 | 4. **dequeue**: Dequeue is like vector only but it means double ended queue and we can delete and insert from both the ends. List, forward_list and dequeue has same set of functions. Only in vector we can't insert from front. 23 | 24 | 5. **priority_queue**: **Heap** data structure. **Max-heap** to be specific. push(), pop(),empty(),size() same operations as stack present for priority queue as well. Priority queue basically means the largest element from the queue will be deleted. 25 | 26 | 6. **stack**: Follows LIFO has same set of operations as priority queue we see above. 27 | 28 | 7. **set**: Collection of elements that contains unique elements and does not maintains the order. 29 | 30 | 8. **Multiset**: Same as set but allows duplicates. 31 | 32 | 9. **Map**: To store **key-value** pairs. Like Dictionary in Python. Contains unique keys, can't have 2 keys with same content. Uses hash tables. Similarly we have **multimap** as you might have guessed this allows keys to be duplicated just like multiset. Duplicate keys are allowed but same key-value pair is still not allowed. 33 | 34 | ## Iterators 35 | 36 | - Ref:**stl.cpp** -------------------------------------------------------------------------------- /19. STL/list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | list v = {10, 20, 40, 90}; // Change list to forward list to have single linked list, set to use set, no push_back for set we use insert for set. 8 | v.push_back(25); 9 | v.push_back(35); 10 | v.pop_back(); 11 | 12 | /* 13 | for (int x : v) // for each int x in vector int v we iterate 14 | { 15 | cout << x << endl; 16 | } 17 | */ 18 | 19 | list::iterator itr; 20 | 21 | for (itr = v.begin(); itr != v.end(); itr++) 22 | { 23 | cout << *itr << endl; 24 | } 25 | } -------------------------------------------------------------------------------- /19. STL/map.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | map m; 8 | m.insert(pair(1, "Cosmic")); 9 | m.insert(pair(2, "Darlene")); 10 | m.insert(pair(3, "Tyler")); 11 | 12 | map::iterator iter; 13 | for (iter = m.begin(); iter != m.end(); iter++) 14 | { 15 | cout << iter->first << " " << iter->second << endl; 16 | } 17 | 18 | // We may use the function find to search by key, it returns iterator position for that value 19 | map::iterator iter2; 20 | cout << "Search Results\n"; 21 | iter2 = m.find(2); 22 | cout << iter2->first << " " << iter2->second << endl; 23 | } -------------------------------------------------------------------------------- /19. STL/stl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | vector v = {10, 20, 40, 90}; // By default creates vector of size 16 mention size by doing v(size) 8 | v.push_back(25); // Adds 25 to the vector object v 9 | v.push_back(35); 10 | v.pop_back(); //Remove value at the end. 11 | 12 | // Iterate over list of items 13 | 14 | // Method 1 use for each loop introduced in C11. 15 | 16 | /* 17 | for (int x : v) // for each int x in vector int v we iterate 18 | { 19 | cout << x << endl; 20 | } 21 | */ 22 | 23 | // Method 2 : Iterator class available and use those. We create an object of iterator and iterate through all the list of elements. 24 | vector::iterator itr; 25 | // vector::iterator itr = v.begin(); //Object of class iterator called itr and to it we assign the object and we pass the object and function begin on it. 26 | // Begin is a function available in all the containers, begin just gives the starting address of the container and end gives end of the collection. 27 | // e.g. 28 | for (itr = v.begin(); itr != v.end(); itr++) 29 | { 30 | cout << *itr << endl; // * is used as iterator is like a pointer to the elements inside the collection. 31 | } 32 | } -------------------------------------------------------------------------------- /19. STL/vector.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | int main() 6 | { 7 | vector v = {10, 20, 40, 90}; // By default creates vector of size 16 mention size by doing v(size) 8 | v.push_back(25); 9 | v.push_back(35); 10 | v.pop_back(); 11 | 12 | // Method 1 use for each loop introduced in C11. 13 | 14 | /* 15 | for (int x : v) // for each int x in vector int v we iterate 16 | { 17 | cout << x << endl; 18 | } 19 | */ 20 | 21 | // Method 2 : Iterator class available and use those. We create an object of iterator and iterate through all the list of elements. 22 | vector::iterator itr; 23 | for (itr = v.begin(); itr != v.end(); itr++) 24 | { 25 | cout << *itr << endl; // * is used as iterator is like a pointer to the elements inside the collection. 26 | } 27 | } -------------------------------------------------------------------------------- /20. C11/auto.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | float fun() 4 | { 5 | return 2.34f; 6 | } 7 | int main() 8 | { 9 | auto x = 2 * 5.7 + 'a'; 10 | auto b = fun(); 11 | cout << x << endl 12 | << b << endl; 13 | return 0; 14 | } -------------------------------------------------------------------------------- /20. C11/ellipsis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int sum(int n, ...) 7 | { 8 | va_list list; // Make list type of object to store stuff from ... variable args 9 | va_start(list, n); // Mention how many arguments you need. 10 | 11 | int x; 12 | int s = 0; 13 | for (int i = 0; i < n; i++) 14 | { 15 | x = va_arg(list, int); // To get the arguments of defined type. 16 | s += x; 17 | } 18 | return s; 19 | } 20 | 21 | int main() 22 | { 23 | cout << sum(3, 10, 20, 30) << endl; 24 | } -------------------------------------------------------------------------------- /20. C11/ellipsis2.cpp: -------------------------------------------------------------------------------- 1 | /* va_start example */ 2 | #include /* printf */ 3 | #include /* va_list, va_start, va_arg, va_end */ 4 | 5 | void PrintFloats(int n, ...) 6 | { 7 | int i; 8 | double val; 9 | printf("Printing floats:"); 10 | va_list vl; 11 | va_start(vl, n); 12 | for (i = 0; i < n; i++) 13 | { 14 | val = va_arg(vl, double); 15 | printf(" [%.2f]", val); 16 | } 17 | va_end(vl); 18 | printf("\n"); 19 | } 20 | 21 | int main() 22 | { 23 | PrintFloats(3, 3.14159, 2.71828, 1.41421); 24 | return 0; 25 | } -------------------------------------------------------------------------------- /20. C11/final.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // class Parent // Works without any error if we use this, but on marking Parent:final class Child is not able to inherit that Parent class no more. Final is used to restrict inheritance. 5 | class Parent //: final 6 | { 7 | // Only virtual functions are allowed to be marked as final 8 | virtual void show() final 9 | { 10 | cout << "Parent Final"; 11 | } 12 | }; 13 | 14 | class Child : Parent 15 | { 16 | // As parent class is inherited so we are not allowed to define show() as virtual function is marked as final in class Parent 17 | // Final functions of parent class can't be overrided in child Class. 18 | // Final keyword used to restrict inheritance as well as overriding of functions. 19 | /* 20 | void show() 21 | { 22 | 23 | } 24 | */ 25 | }; 26 | 27 | int main() 28 | { 29 | } -------------------------------------------------------------------------------- /20. C11/lambda.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // Lambda functions are used to define functions with no name. 4 | int main() 5 | { 6 | // [capture_list](parameter_list)->return type(body); 7 | // Define and call the function 8 | string f = []() { return "Hello\n"; }(); 9 | 10 | [](int x, int y) { cout << "Sum: " << x + y << endl; }(10, 5); 11 | 12 | int c = [](int x, int y) { return x + y; }(10, 5); 13 | cout << c << endl; 14 | 15 | int s = [](int x, int y) -> int { return x + y; }(10, 5); 16 | 17 | // Pass in already declared variables to the function 18 | 19 | int a = 10, b = 15; 20 | [a, b]() { cout << a << " " << b << endl; }(); // Allows us only to display not modify the variables 21 | 22 | // To modify capture the variables by reference 23 | [&a, &b]() { cout << ++a << " " << ++b << endl; }(); 24 | } -------------------------------------------------------------------------------- /20. C11/unique_ptr.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include // For unique_ptr 3 | 4 | using namespace std; 5 | 6 | class Rectangle 7 | { 8 | int len; 9 | int bre; 10 | 11 | public: 12 | Rectangle(int len, int bre) 13 | { 14 | this->len = len; 15 | this->bre = bre; 16 | } 17 | int area() 18 | { 19 | return len * bre; 20 | } 21 | }; 22 | 23 | int main() 24 | { 25 | unique_ptr ptr(new Rectangle(10, 5)); // Object created in heap and given to unique_ptr and pointer name is ptr 26 | cout << "Display using unique_ptr, ptr= " << ptr->area() << endl; 27 | // unique_ptr ptr2(ptr); // Gives error as we passed unique_ptr ptr to ptr2, instead we can remove or pass on ptr to ptr2 using move in following manner 28 | unique_ptr ptr2; 29 | ptr2 = move(ptr); 30 | cout << "Display using ptr2 = move(ptr), ptr2= " << ptr2->area() << endl; 31 | 32 | // Shared Pointer 33 | shared_ptr ptr_shared_1(new Rectangle(5, 5)); 34 | cout << "-------------------------------------" << endl; 35 | cout << "ptr_shared_1(new Rectangle(5, 5): " << ptr_shared_1->area() << endl; 36 | cout << "ptr_shared_1.use_count() = " << ptr_shared_1.use_count() << endl; 37 | shared_ptr ptr_shared_2; 38 | ptr_shared_2 = ptr_shared_1; 39 | cout << "ptr_shared_2(new Rectangle(5, 5): " << ptr_shared_2->area() << endl; 40 | cout << "ptr_shared_2.use_count() = " << ptr_shared_2.use_count() << endl; 41 | cout << "-------------------------------------" << endl; 42 | // Java is a managed language that runs inside the JVM, C++ is unmanaged and runs independently, so C++ has smart classes which acts as smart pointers to achieve similar functionality as garbage collection present inside of managed languages. 43 | } -------------------------------------------------------------------------------- /21. Project - Banking System/Bank.data: -------------------------------------------------------------------------------- 1 | 1 2 | Anmol 3 | Tomer 4 | 10000 5 | -------------------------------------------------------------------------------- /21. Project - Banking System/README.md: -------------------------------------------------------------------------------- 1 | ## Banking System Project -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Anmol Tomer 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cpp_deep_dive 2 | 3 | - Here I bring you the notes of cpp exclusively from Sir Abdul Bari's Deep Dive in C++ Course on [Udemy](https://www.udemy.com/course/cpp-deep-dive/) 4 | - Please have a look and feel free to ask any questions. 5 | - I would love to help you out. 6 | - Thanks!! 7 | 8 | ## Contents : 9 | 10 | **[01. Introduction
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/01.%20Introduction)** 11 | 12 | **[02. C++ Basics
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/02.%20C%2B%2B%20Basics)** 13 | 14 | **[03. Conditional Statements
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/03.%20Conditional%20Statements)** 15 | 16 | **[04. Loops
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/04.%20Loops)** 17 | 18 | **[05. Arrays
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/05.%20Arrays)** 19 | 20 | **[06. Pointers
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/06.%20Pointers)** 21 | 22 | **[07. Functions
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/07.%20Functions)** 23 | 24 | **[08. Intro to OOP
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/08.%20Intro%20to%20OOP)** 25 | 26 | **[09. Operator Overloading
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/09.%20Operator%20Overloading)** 27 | 28 | **[10. Inheritance
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/10.%20Inheritance)** 29 | 30 | **[11. Base Class Pointer Derived Class Object
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/11.%20Base%20Class%20Pointer%20Derived%20Class%20Object)** 31 | 32 | **[12. Polymorphism
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/12.%20Polymorphism)** 33 | 34 | **[13. Friend and Static Member
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/13.%20Friend%20and%20Static%20Member)** 35 | 36 | **[14. Exception Handling
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/14.%20Exception%20Handling)** 37 | 38 | **[15. Template Functions and Classes
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/15.%20Template%20Functions%20and%20Classes)** 39 | 40 | **[16. Constant Preprocessors and namespaces
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/16.%20Constants%20Preprocessors%20or%20Directives%20and%20Namespaces)** 41 | 42 | **[17. Destructors and Virtual Destructors
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/17.%20Destructors%20and%20Virtual%20Destructors)** 43 | 44 | **[18. IO Streams
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/18.%20IO%20Streams)** 45 | 46 | **[19. STL
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/19.%20STL)** 47 | 48 | **[20. C11
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/20.%20C11)** 49 | 50 | **[21. Project - Banking System
](https://github.com/AnmolTomer/cpp_deep_dive/tree/master/21.%20Project%20-%20Banking%20System)** 51 | --------------------------------------------------------------------------------