NOTES


 

"#include<iostream>" - this text is called a header file.

1)  In this line of code include is a keyword used to add libraries in our program. "iostream" is the name of a library, added to our program. The iostream library helps us to get input data and show output data. The iostream library also has many more uses; it is not only limited to input and output.


2)  "int main() {" - In this line of code, "int" is a return type which is called integer and "main()" is a function, the brackets "()" denotes that it is a function. The curly brace "{" indicates that it is an opening of a function, and the curly brace "}" indicates that it is the closing of a function.


 3)  "return 0" - In this line of code, the return keyword will return 0 as an integer to our main function "int main()" as we have discussed before. Returning 0 as a value to the main function means successful termination of the program.

 4)  'std::cout<<" hello world";' - In this line of code "std" is a namespace, "::" is the scope resolution operator and "cout<<" is a function which is used to output data, "hello world" is our output string and ";" is used to end a statement. The code "std::cout" tells the compiler that the "cout" identifier resides in the std namespace. 



Comments in C++

A comment is a human-readable text in the source code, which is ignored by the compiler. There are two ways to write comments.

Single-Line Comments: 1st way is to use" //" before a single line of text to make it unparsable by the compiler.

Multi-Line Comments: 2nd way is to use "/*" as the opening and "*/" as the closing of the comment. We then write text in between them. If we write text without this, the compiler will try to read the text and will end up giving an error.  Figure 1 shows examples of these comments.



 Variable can be defined as a container to hold data. Variables are of different types, for example:

  1. Int-> Int is used to store integer data e.g (-1, 2, 5,-9, 3, 100).
  2. Float-> Float is used to store decimal numbers e.g (0.5, 1.05, 3.5, 10.5)
  3. Char-> Char is used to store a single character e.g. ('a', 'b',' c', 'd')
  4. Boolean-> Boolean is used to store "true" or "false."
  5. Double-> Double is also used to store decimal numbers but has more precision than float, e.g. (10.5895758440339...)

Base on scope, variables can be classified into two types:

  • Local variables
  • Global variables


Local variables:

Local variables are declared inside the braces of any function and can be assessed only from there. 

Global variables:

Global variables are declared outside any function and can be accessed from anywhere.

Can we declare Local and global variable with the same name:  YES.

In that case local variable will gain priority.


Data Types

Data types define the type of data that a variable can hold; for example, an integer variable can hold integer data, a character can hold character data, etc.

Data types in C++ are categorized into three groups:

  • Built-in
  • User-defined
  • Derived
1. Built-in Data Types in C++:
  • Int
  • Float
  • Char
  • Double
  • Boolean
2. User-Defined Data Types in C++:
  • Struct
  • Union
  • Enum

3. Derived Data Types in C++:
  • Array
  • Pointer
  • Function

Rules to Declare Variables in C++

  • Variable names in C++ language can range from 1 to 255
  • Variable names must start with a letter of the alphabet or an underscore
  • After the first letter, variable names can contain letters and numbers
  • Variable names are case sensitive
  • No spaces and special characters are allowed
  • We cannot use reserved keywords as a variable name

Reserved keywords in C++

Reserved keywords are those keywords that are used by the language itself, which is why these keywords are not available for re-definition or overloading. In short, you cannot create variables with these names. 


Header Files in C++

"#include" is used in C++ to import header files in our C++ program. The reason to introduce the "<iostream>" header file into our program is that functions like "cout" and "cin" are defined in that header file. There are two types of header files:

System Header Files

System header files ships with the compiler. For example, “#include <iostream>”. To see the references for header files click here

 User-Defined Header Files

The programmer writes User-defined header files himself. To include your header file in the program, you first need to make a header file in the current directory, and then you can add it. 

For example :

We have to make a file named "arvind.h"

And then save it. 

Program:

#include "arvind.h"



Reference Variable

Reference variables can be defined as another name for an already existing variable. These are also called an alias. For example, let us say we have a variable with the name of "sum", but we also want to use the same variable with the name of "add", to do that we will make a reference variable with the name of "add". The example code for the reference variable is shown in figure 5.

Figure 5: Reference Variable Code

As shown in figure 5, we initialized a variable "x" with the value "455". Then we assigned the value of "x" to a reference variable "y". The ampersand "&" symbol is used with the "y" variable to make it reference variable. Now the variable "y" will start referring to the value of the variable "x"



Float, Double and Long Double Literals

The main reason to discuss these literals was to tell you an important concept about them. The float, double and long double literals program is shown in figure 3.

Figure 3: Float, Double & Long Double Literals

So the crucial concept which I am talking about is that in C++ language, double is the default type given to a  decimal literal (34.4 is double by default and not float), so to use it as float, you have to specify it like "34.4F," as shown in figure 3. To display the size of float, double, and long double literals, we have used a "sizeof" operator. The output of this program is shown in figure 4.



Typecasting

Typecasting can be defined as converting one data type into another. Example code for type casting is shown in figure 7.

Figure 7: Typecasting Example Code

As shown in figure 7, we have initialized two variables, integer "a" and float "b". After that, we converted an integer variable "a" into a float variable and float variable "b" into an integer variable. In C++, there are two ways to typecast a variable, either using "(float)a" or using "float(a)". The output for the above program is shown in figure 8.


Manipulator

In C++ programming, language manipulators are used in the formatting of output. The two most commonly used manipulators are: "endl" and "setw".

  • "endl" is used for the next line.
  • "setw" is used to specify the width of the output.

An example program to show the working of a manipulator is shown in figure 3.




Figure 3: Manipulators in C++

As shown in figure 3, we have initialized three integer variables "a, b, c". First, we printed all the three variables and used "endl" to print each variable in a new line. After that, we again printed the three variables and used "setw(4)," which will set there width to "4". The output for the following program is shown in figure 4.

Figure 4: Manipulators Program




EXAMPLE PROGRAM OF MANIPULATOR:
#include<iostream>
#include<iomanip>

using namespace std;

int main(){
    // int a = 34; 
    // cout<<"The value of a was: "<<a;
    // a = 45; 
    // cout<<"The value of a is: "<<a;
    // Constants in C++
    // const int a = 3;
    // cout<<"The value of a was: "<<a<<endl;
    // a = 45; // You will get an error because a is a constant
    // cout<<"The value of a is: "<<a<<endl;

    // Manipulators in C++
    // int a =3, b=78, c=1233;
    // cout<<"The value of a without setw is: "<<a<<endl;
    // cout<<"The value of b without setw is: "<<b<<endl;
    // cout<<"The value of c without setw is: "<<c<<endl;

    // cout<<"The value of a is: "<<setw(4)<<a<<endl;
    // cout<<"The value of b is: "<<setw(4)<<b<<endl;
    // cout<<"The value of c is: "<<setw(4)<<c<<endl;


    // Operator Precedence
    int a =3, b=4;
    // int c = (a*5)+b;
    int c = ((((a*5)+b)-45)+87);
    cout<<c;
    return 0;
}





Break Statements & Continue Statements in C++

Break-->If the condition is true then, Loop break suddenly. 
Continue-->Skip that condition. 



Pointers in C++

A pointer is a data type which holds the address of other data type. The “&” operator is called “address off" operator, and the "*” operator is called “value at” dereference operator. An example program for pointers is shown in figure 1.


The output of the following program is shown in figure 2.

Figure 2: Pointer Program Outpu

Output:



Pointer to Pointer

Pointer to Pointer is a simple concept, in which we store the address of one Pointer to another pointer. An example program for Pointer to Pointer is shown in figure 7.

Figure 7: Pointer to Pointer Example Program

The output for the following program is 

Figure 8: Pointer to Pointer Example Program Output






Pointers and Arrays

Storing the address of an array into pointer is different than storing the address of a variable into the pointer because the name of the array is an address of the first index of an array. So to use ampersand "&" with the array name for assigning the address to a pointer is wrong.

  • &Marks --> Wrong
  • Marks --> address of the first block

An example program for storing the starting address of an array in the pointer is shown in code snippet 4.

int* p = marks;
cout<<"The value of marks[0] is "<<*p<<endl;
   

Code Snippet 4: Pointer and Array Program

As shown in code snippet 7, we have assigned the address of array “marks” to the pointer variable “*p” and then printed the pointer “*p”. The main thing to note here is that the value at the pointer “*p” is the starting address of the array “marks”. The output for the following program is shown in figure 4.

Figure 4: Pointer and Array Program Output

As shown in figure 4, we have printed the value at pointer "*p", and it has shown us the value of the first index of the array "marks" because the pointer was pointing at the first index of an array and the value at that index was "23". If we want to access the 2nd index of an array through the pointer, we can simply increment the pointer with 1. For example: "*(p+1)" will give us the value of the 2nd index of an array. An example program to print the values of an array through the pointer is shown in code snippet 5.

int* p = marks;
    cout<<"The value of *p is "<<*p<<endl;
    cout<<"The value of *(p+1) is "<<*(p+1)<<endl;
    cout<<"The value of *(p+2) is "<<*(p+2)<<endl;
    cout<<"The value of *(p+3) is "<<*(p+3)<<endl; 
 

Code Snippet 5: Pointer and Array Program 2

As shown in code snippet 5, 1st we have printed the value at pointer “*p”; 2nd we have printed the value at pointer “*(p+1)”; 3rd we have printed the value at pointer “*(p+2)”; 4th we have printed the value at pointer “*(p+3)". This program will output the values at "0, 1, 2, 3" indices of an array "marks". The output of the following program is shown in figure 5.

Figure 5: Pointer and Array Program 2 Output






Structures in C++

The structure is a user-defined data type that is available in C++. Structures are used to combine different types of data types, just like an array is used to combine the same type of data types. An example program for creating a structure is shown in Code Snippet 1.

struct employee
{
    /* data */
    int eId; 
    char favChar; 
    float salary; 
};

Code Snippet 1: Creating a Structure Program




As shown in Code Snippet 1, we have created a structure with the name “employee”, in which we have declared three variables of different data types (eId, favchar, salary). As we have created a structure now we can create instances of our structure employee. An example program for creating instances of structure employees is shown in Code Snippet 2.

 int main() {
     struct employee harry;
     harry.eId = 1;
     harry.favChar = 'c';
     harry.salary = 120000000;
     cout<<"The value is "<<harry.eId<<endl; 
     cout<<"The value is "<<harry.favChar<<endl; 
     cout<<"The value is "<<harry.salary<<endl; 
     return 0;
}

Code Snippet 2: Creating Structure instances

As shown in Code Snippet 2, 1st we have created a structure variable “harry” of type “employee”, 2nd we have assigned values to (eId, favchar, salary) fields of the structure employee and at the end we have printed the value of “salary”.

Another way to create structure variables without using the keyword “struct” and the name of the struct is shown in Code Snippet 3.




typedef struct employee
{
    /* data */
    int eId; //4
    char favChar; //1
    float salary; //4
} ep;

Code Snippet 3: Creating Structure Program 2

As shown in Code Snippet 3, we have used a keyword “typedef” before struct and after the closing bracket of structure, we have written “ep”. Now we can create structure variables without using the keyword “struct” and name of the struct. An example is shown in Code Snippet 4.


int main(){
ep harry;
    struct employee shubham;
    struct employee rohanDas;
    harry.eId = 1;
    harry.favChar = 'c';
    harry.salary = 120000000;
    cout<<"The value is "<<harry.eId<<endl; 
    cout<<"The value is "<<harry.favChar<<endl; 
    cout<<"The value is "<<harry.salary<<endl; 
    return 0;
}

As shown in Code Snippet 4, we have created a structure instance “harry” by just writing “ep” before it.




Unions in C++

Unions are similar to structures but they provide better memory management then structures.  Unions use shared memory so only 1 variable can be used at a time. An example program to create unions is shown in Code Snippet 5.

union money
{
    /* data */
    int rice; //4
    char car; //1
    float pounds; //4
};

Code Snippet 5: Creating Unions Program

As shown in Code Snippet 5, we have created a union with the name “money” in which we have declared three variables of different data types (rice, car, pound). The main thing to note here is that:

  • We can only use 1 variable at a time otherwise the compiler will give us a garbage value
  • The compiler chooses the data type which has maximum memory for the allocation.

An example program for creating an instance of union money is shown in Code Snippet 6.

int main(){
        union money m1;
        m1.rice = 34;
        cout<<m1.rice;
        return 0;
}

Code Snippet 6: Creating a Union Instance

As shown in Code Snippet 6, 1st we have created a union variable “m1” of type “money”, 2nd we have assigned values to (rice) fields of the union money, and in the end, we have printed the value of “rice”. The main thing to note here is that once we have assigned a value to the union field “rice”, now we cannot use other fields of the union otherwise we will get garbage value. The output for the following program is shown in figure 1.

Figure 1: Creating Union Instance Output


Enums in C++

Enums are user-defined types which consist of named constants. Enums are used to make the program more readable. An example program for enums is shown in Code Snippet 8.

int main(){
    enum Meal{ breakfast, lunch, dinner};
    Meal m1 = lunch;
    cout<<m1;
    return 0;
}
    

Code Snippet 7: Enums Program

As shown in Code Snippet 7, 1st we have created an enum “Meal” in which we have stored three named constants (breakfast, lunch, dinner). 2nd we have assigned the value of “lunch” to the variable “m1” and at the end, we have printed “m1”. The main thing to note here is that (breakfast, lunch, dinner) are constants; the value for “breakfast” is “0”, the value for “lunch” is “1” and the value for “dinner” is “2”. The output for the following program is shown in figure 2.

Figure 2: Enums Program Output

Code as described/written in the video

#include<iostream>
using namespace std;

typedef struct employee
{
    /* data */
    int eId; //4
    char favChar; //1
    float salary; //4
} ep;

union money
{
    /* data */
    int rice; //4
    char car; //1
    float pounds; //4
};


int main(){
    enum Meal{ breakfast, lunch, dinner};
    Meal m1 = lunch;
    cout<<(m1==2);
    // cout<<breakfast;
    // cout<<lunch;
    // cout<<dinner; 
    // union money m1;
    // m1.rice = 34;
    // m1.car = 'c';
    // cout<<m1.car;

    // ep harry;
    // struct employee shubham;
    // struct employee rohanDas;
    // harry.eId = 1;
    // harry.favChar = 'c';
    // harry.salary = 120000000;
    // cout<<"The value is "<<harry.eId<<endl; 
    // cout<<"The value is "<<harry.favChar<<endl; 
    // cout<<"The value is "<<harry.salary<<endl; 
    return 0;
}




Call by Value in C++

Call by value is a method in C++ to pass the values to the function arguments. In case of call by value the copies of actual parameters are sent to the formal parameter, which means that if we change the values inside the function that will not affect the actual values. An example program for the call by value is shown in Code Snippet 1.

void swap(int a, int b){ //temp a b
    int temp = a;        //4   4  5   
    a = b;               //4   5  5
    b = temp;            //4   5  4 
}

Code Snippet 1: Call by Value Swap Function

As shown in Code Snippet 1, we created a swap function which is taking two parameters “int a” and “int b”. In function body values of the variable, “a” and “b” are swapped.  An example program is shown in Code Snippet 2, which calls the swap function and passes values to it.

int main(){
    int x =4, y=5;
    cout<<"The value of x is "<<x<<" and the value of y is "<<y<<endl;
    swap(x, y); 
    cout<<"The value of x is "<<x<<" and the value of y is "<<y<<endl; 
    return 0;
}

Code Snippet 2: Passing Values to Swap Function

As shown in Code Snippet 2, we have initialized two integer variables “a” and “b” and printed their values. Then we called a “swap” function and passed values of variables “a” and “b” and again printed the values of variables “a” and “b”. The output for the following program is shown in figure 1.


The value of x is 4 and the value of y is 5

The value of x is 4 and the value of y is 5


Figure 1: Call by Value Swap Function Output


Call by Pointer in C++

A call by the pointer is a method in C++ to pass the values to the function arguments. In the case of call by pointer, the address of actual parameters is sent to the formal parameter, which means that if we change the values inside the function that will affect the actual values. An example program for the call by reference is shown in Code Snippet 3.

// Call by reference using pointers
void swapPointer(int* a, int* b){ //temp a b
    int temp = *a;          //4   4  5   
    *a = *b;               //4   5  5
    *b = temp;            //4   5  4 
}

Code Snippet 3: Call by Pointer Swap Function

As shown in Code Snippet 3, we created a swap function which is taking two pointer parameters “int* a” and “int* b”. In function body values of pointer variables, “a” and “b” are swapped.  An example program is shown in Code Snippet 4, which calls the swap function and passes values to it.

int main(){
    int x =4, y=5;
    cout<<"The value of x is "<<x<<" and the value of y is "<<y<<endl;
    swapPointer(&x, &y);   //This will swap a and b using pointer reference
    cout<<"The value of x is "<<x<<" and the value of y is "<<y<<endl; 
    return 0;
}

Code Snippet 4: Passing Values to Call by Pointer Swap Function

As shown in Code Snippet 4, we have initialized two integer variables “a” and “b” and printed their values. Then we called a “swap” function and passed addresses of variables “a” and “b” and again printed the values of variables “a” and “b”. The output for the following program is shown in figure 2.

Figure 2: Call by Pointer Swap Function Output


As shown in figure 2, the values of “a” and “b” are swapped when the swap function is called. So the main point here is that when the call by pointer method is used it changes the actual values because addresses of actual values are sent to the function




Call by Reference in C++

Call by reference is a method in C++ to pass the values to the function arguments. In the case of call by reference, the reference of actual parameters is sent to the formal parameter, which means that if we change the values inside the function that will affect the actual values. An example program for a call by reference is shown in Code Snippet 5.

void swapReferenceVar(int &a, int &b){    //temp a b
    int temp = a;          //4   4  5   
    a = b;               //4   5  5
    b = temp;            //4   5  4 
}

Code Snippet 5: Call by Reference Swap Function

As shown in Code Snippet 5, we created a swap function that is taking reference of “int &a” and “int &b” as parameters. In function body values of variables, “a” and “b” are swapped.  An example program is shown in Code Snippet 6, which calls the swap function and passes values to it.

int main(){
    int x =4, y=5;
    cout<<"The value of x is "<<x<<" and the value of y is "<<y<<endl;
    swapReferenceVar(x, y); //This will swap a and b using reference variables
    cout<<"The value of x is "<<x<<" and the value of y is "<<y<<endl; 
    return 0;
}

Code Snippet 6: Passing Values to Call by Reference Swap Function

As shown in Code Snippet 6, we have initialized two integer variables “a” and “b” and printed their values. Then we called a “swap” function and passed variables “a” and “b” and again printed the values of variables “a” and “b”. The output for the following program is shown in figure 3.

Figure 3: Call by Reference Swap Function Output

As shown in figure 3, the values of “a” and “b” are swapped when the swap function is called. So the main point here is that when the call by reference method is used it changes the actual values because references of actual values are sent to the function.



Code as described/written in the video

#include<iostream>
using namespace std;

int sum(int a, int b){
    int c = a + b;
    return c;
}

// This will not swap a and b
void swap(int a, int b){ //temp a b
    int temp = a;        //4   4  5   
    a = b;               //4   5  5
    b = temp;            //4   5  4 
}

// Call by reference using pointers
void swapPointer(int* a, int* b){ //temp a b
    int temp = *a;          //4   4  5   
    *a = *b;               //4   5  5
    *b = temp;            //4   5  4 
}

// Call by reference using C++ reference Variables
// int & 
void swapReferenceVar(int &a, int &b){ //temp a b
    int temp = a;          //4   4  5   
    a = b;               //4   5  5
    b = temp;            //4   5  4 
    // return a;
}

int main(){
    int x =4, y=5;
    // cout<<"The sum of 4 and 5 is "<<sum(a, b);
    cout<<"The value of x is "<<x<<" and the value of y is "<<y<<endl;
    // swap(x, y); // This will not swap a and b
    // swapPointer(&x, &y); //This will swap a and b using pointer reference
    swapReferenceVar(x, y); //This will swap a and b using reference variables
    // swapReferenceVar(x, y) = 766; //This will swap a and b using reference variables
    cout<<"The value of x is "<<x<<" and the value of y is "<<y<<endl; 
    return 0;
}






Inline Functions in C++

Inline functions are used to reduce the function call. When one function is being called multiply times in the program it increases the execution time, so inline function is used to reduce time and increase program efficiency. If the inline function is being used when the function is called, the inline function expands the whole function code at the point of a function call, instead of running the function. Inline functions are considered to be used when the function is small otherwise it will not perform well. Inline is not recommended when static variables are being used in the function. An example of an inline function is shown in Code Snippet 1.

inline int product(int a, int b){
    return a*b;
}

Code Snippet 1: Inline function

As shown in Code Snippet 1, 1st inline keyword is used to make the function inline. 2nd a product function is created which has two arguments and returns the product of them. Now we will call the product function multiple times in our main program which is shown in Code Snippet 2.

int main(){
    int a, b;
    cout<<"Enter the value of a and b"<<endl;
    cin>>a>>b;
    cout<<"The product of a and b is "<<product(a,b)<<endl;
    cout<<"The product of a and b is "<<product(a,b)<<endl;
    cout<<"The product of a and b is "<<product(a,b)<<endl;
    cout<<"The product of a and b is "<<product(a,b)<<endl;
    cout<<"The product of a and b is "<<product(a,b)<<endl;
    cout<<"The product of a and b is "<<product(a,b)<<endl;
    cout<<"The product of a and b is "<<product(a,b)<<endl;
    cout<<"The product of a and b is "<<product(a,b)<<endl;
    return 0;
}

Code Snippet 2: Calling Inline Product Function

As shown in Code Snippet 2, we called the product function multiple times. The main thing to note here is that the function will not run instead of it the function code will be copied at the place where the function is being called. This will increase the execution time of the program because the compiler doesn’t have to copy the values and get the return value again and again from the compiler. The output of the following program is shown in figure 1.

Figure 1: Inline Function Output



Default Arguments in C++

Default arguments are those values which are used by the function if we don’t input our value. It is recommended to write default arguments after the other arguments. An example program for default arguments is shown in Code Snippet 3.

float moneyReceived(int currentMoney, float factor=1.04){
    return currentMoney * factor;
}

int main(){
    int money = 100000;
    cout<<"If you have "<<money<<" Rs in your bank account, you will recive "<<moneyReceived(money)<< "Rs after 1 year"<<endl;
    cout<<"For VIP: If you have "<<money<<" Rs in your bank account, you will recive "<<moneyReceived(money, 1.1)<< " Rs after 1 year";
    return 0;
}

Code Snippet 3: Default Argument Example Program


As shown in Code Snippet 3, we created a “moneyReceived” function which has two arguments “int currentMoney” and “float factor=1.04”. This function returns the product of “currentMoney” and “factor”. In our main function, we called “moneyReceived” function and passed one argument “money”. Again we called “moneyReceived” function and passed two arguments ”money” and “1.1”. The main thing to note here is that when we passed only one argument “money” to the function at that time the default value of the argument “factor” will be used. But when we passed both arguments then the default value will not be used. The output for the following program is shown in figure 2.

Figure 2: Default Argument Example Program Output



Constant Arguments in C++

Constant arguments are used when you don’t want your values to be changed or modified by the function. An example of constant arguments is shown in Code Snippet 4.

int strlen(const char *p){

}

Code Snippet 4: Constant Arguments Example

As shown in Code Snippet 4, we created a “strlen” function which takes a constant argument “p”. As the argument is constant so its value won’t be modified.

Code as described/written in the video

#include<iostream>
using namespace std;

inline int product(int a, int b){
    // Not recommended to use below lines with inline functions
    // static int c=0; // This executes only once
    // c = c + 1; // Next time this function is run, the value of c will be retained
    return a*b;
}

float moneyReceived(int currentMoney, float factor=1.04){
    return currentMoney * factor;
}

// int strlen(const char *p){

// }
int main(){
    int a, b;
    // cout<<"Enter the value of a and b"<<endl;
    // cin>>a>>b;
    // cout<<"The product of a and b is "<<product(a,b)<<endl;
    int money = 100000;
    cout<<"If you have "<<money<<" Rs in your bank account, you will recive "<<moneyReceived(money)<< "Rs after 1 year"<<endl;
    cout<<"For VIP: If you have "<<money<<" Rs in your bank account, you will recive "<<moneyReceived(money, 1.1)<< " Rs after 1 year";
    return 0;
}






Recursion and Recursive Function

When a function calls itself it is called recursion and the function which is calling itself is called a recursive function. The recursive function consists of a base case and recursive condition. It is very important to add a base case in recursive function otherwise recursive function will never stop executing. An example of the recursive function is shown in Code Snippet 1.

int factorial(int n){
    if (n<=1){
        return 1;
    }
    return n * factorial(n-1);
}

Code Snippet 1: Factorial Recursive Function


As shown in Code Snippet 1, we created a “factorial” function which takes one argument. In the function body, there is a base case which checks that if the value of variable “n” is smaller or equal to “1” if the condition is “true” return “1”. And there is a recursive condition that divides the bigger value to smaller values and at the end returns a factorial. These are the steps which will be performed by recursive condition:

  • 4 * factorial( 4-1 )
  • 4 * 3 * factorial( 3-1 )
  • 4* 3 * 2 * factorial( 2-1 )
  • 4 * 3 * 2 * 1

An example to pass the value to the recursive factorial function is shown in Code Snippet 2

int main(){
    int a;
    cout<<"Enter a number"<<endl;
    cin>>a;
    cout<<"The factorial of "<<a<< " is "<<factorial(a)<<endl;
    return 0;
}

As shown in Code Snippet 2, we created an integer variable “a”, which takes input at the runtime and that value is passed to the factorial function. The output for the following program is shown in figure 1.

Figure 1: Factorial Recursive Function Output


As shown in figure 1, we input the value “4” and it gives us the factorial of it which is “24”. Another example of a recursive function for the Fibonacci series is shown in Code Snippet 3.

int fib(int n){
    if(n<2){
        return 1;
    }
    return fib(n-2) + fib(n-1);
}

Code Snippet 3: Fibonacci Recursive Function

As shown in Code Snippet 3, we created a “fib” function which takes one argument. In the function body, there is a base case which checks that if the value of variable “n” is smaller than “2”, if the condition is “true” return “1”. And there is a recursive condition that divides the bigger value to smaller values and at the end returns a Fibonacci number. An example to pass the value to the Fibonacci function is shown in Code Snippet 4.

int main(){
    int a;
    cout<<"Enter a number"<<endl;
    cin>>a;
    cout<<"The term in fibonacci sequence at position "<<a<< " is "<<fib(a)<<endl;
    return 0;
}

Code Snippet 4: Fibonacci Recursive Function Call


Figure 2: Fibonacci Recursive Function Output

As shown in figure 2, 1st we input the value “5” and it gives us the Fibonacci number at that place which is “8”. 2nd we input the value “6” and it gives us the Fibonacci number at that place which is “13”.

One thing to note here is that recursive functions are not always the best option. They perform well in some problems but not in every problem.





Function Overloading in C++

Function overloading is a process to make more than one function with the same name but different parameters, numbers, or sequence. An example program to explain function overloading is shown in Code Snippet 1.

int sum(float a, int b){
    cout<<"Using function with 2 arguments"<<endl;
    return a+b;
}

int sum(int a, int b, int c){
    cout<<"Using function with 3 arguments"<<endl;
    return a+b+c;
}

Code Snippet 1: Sum Function Overloading Example




Another example of function overloading is shown in Code Snippet 3.

// Calculate the volume of a cylinder
int volume(double r, int h){
    return(3.14 * r *r *h);
}

// Calculate the volume of a cube
int volume(int a){
    return (a * a * a);
}

// Rectangular box
int volume (int l, int b, int h){
    return (l*b*h);
}

Code Snippet 3: Volume Function Overloading Example


Why Object-Oriented Programming?

Before we discuss object-oriented programming, we need to learn why we need object-oriented programming?

  • C++ language was designed with the main intention of adding object-oriented programming to C language
  • As the size of the program increases readability, maintainability, and bug-free nature of the program decrease.
  • This was the major problem with languages like C which relied upon functions or procedure (hence the name procedural programming language)
  • As a result, the possibility of not addressing the problem adequately was high
  • Also, data was almost neglected, data security was easily compromised
  • Using classes solves this problem by modeling program as a real-world scenario

Difference between Procedure Oriented Programming and Object-Oriented Programming

Procedure Oriented Programming
  • Consists of writing a set of instruction for the computer to follow
  • The main focus is on functions and not on the flow of data
  • Functions can either use local or global data
  • Data moves openly from function to function
Object-Oriented Programming

  • Works on the concept of classes and object
  • A class is a template to create objects
  • Treats data as a critical element
  • Decomposes the problem in objects and builds data and functions around the objects


Basic Concepts in Object-Oriented Programming

  • Classes - Basic template for creating objects
  • Objects – Basic run-time entities
  • Data Abstraction & Encapsulation – Wrapping data and functions into a single unit
  • Inheritance – Properties of one class can be inherited into others
  • Polymorphism – Ability to take more than one forms
  • Dynamic Binding – Code which will execute is not known until the program runs
  • Message Passing – message (Information) call format

Benefits of Object-Oriented Programming

  • Better code reusability using objects and inheritance
  • Principle of data hiding helps build secure systems
  • Multiple Objects can co-exist without any interference
  • Software complexity can be easily managed

Why use classes instead of structures

Classes and structures are somewhat the same but still, they have some differences. For example, we cannot hide data in structures which means that everything is public and can be accessed easily which is a major drawback of the structure because structures cannot be used where data security is a major concern. Another drawback of structures is that we cannot add functions in it.




Classes in C++

Classes are user-defined data-types and are a template for creating objects. Classes consist of variables and functions which are also called class members.

Public Access Modifier in C++

All the variables and functions declared under public access modifier will be available for everyone. They can be accessed both inside and outside the class. Dot (.) operator is used in the program to access public data members directly.

Private Access Modifier in C++

All the variables and functions declared under a private access modifier can only be used inside the class. They are not permissible to be used by any object or function outside the class.




#include<iostream>

using namespace std;


class Employee

{

    private:

        int a, b, c;

    public:

        int d, e;

        void setData(int a1, int b1, int c1); // Declaration

        void getData(){

            cout<<"The value of a is "<<a<<endl;

            cout<<"The value of b is "<<b<<endl;

            cout<<"The value of c is "<<c<<endl;

            cout<<"The value of d is "<<d<<endl;

            cout<<"The value of e is "<<e<<endl;

        }

};


void Employee :: setData(int a1, int b1, int c1){

    a = a1;

    b = b1;

    c = c1;

}


int main(){

    Employee harry;

    // harry.a = 134; -->This will throw error as a is private

    harry.d = 34;

    harry.e = 89;

    harry.setData(1,2,4);

    harry.getData();

    return 0;

}




class Employee{
            // Class definition
} harry, rohan, lovish;

Code Snippet 1: Declaring Objects with Class Declaration


Nesting of Member Functions

If one member function is called inside the other member function of the same class it is called nesting of a member function.



// OOPs - Classes and objects


// C++ --> initially called --> C with classes by stroustroup

// class --> extension of structures (in C)

// structures had limitations

//      - members are public

//      - No methods

// classes --> structures + more

// classes --> can have methods and properties

// classes --> can make few members as private & few as public

// structures in C++ are typedefed

// you can declare objects along with the class declarion like this:

/* class Employee{

            // Class definition

        } harry, rohan, lovish; */

// harry.salary = 8 makes no sense if salary is private


// Nesting of member functions


#include <iostream>

#include <string>

using namespace std;


class binary

{

private:

    string s;

    void chk_bin(void);


public:

    void read(void);

    void ones_compliment(void);

    void display(void);

};


void binary::read(void)

{

    cout << "Enter a binary number" << endl;

    cin >> s;

}


void binary::chk_bin(void)

{

    for (int i = 0; i < s.length(); i++)

    {

        if (s.at(i) != '0' && s.at(i) != '1')

        {

            cout << "Incorrect binary format" << endl;

            exit(0);

        }

    }

}


void binary::ones_compliment(void)

{

    chk_bin();

    for (int i = 0; i < s.length(); i++)

    {

        if (s.at(i) == '0')

        {

            s.at(i) = '1';

        }

       else

        {

            s.at(i) = '0';

        }

    }

}


void binary::display(void)

{

    cout<<"Displaying your binary number"<<endl;

    for (int i = 0; i < s.length(); i++)

    {

        cout << s.at(i);

    }

    cout<<endl;

}


int main()

{

    binary b;

    b.read();

    // b.chk_bin();

    b.display();

    b.ones_compliment();

    b.display();


    return 0;

}




Objects Memory Allocation in C++

The way memory is allocated to variables and functions of the class is different even though they both are from the same class.

The memory is only allocated to the variables of the class when the object is created. The memory is not allocated to the variables when the class is declared. At the same time, single variables can have different values for different objects, so every object has an individual copy of all the variables of the class. But the memory is allocated to the function only once when the class is declared. So the objects don’t have individual copies of functions only one copy is shared among each object.

Arrays in Classes

Arrays are used to store multiple values of the same type. An array is very helpful when multiple variables are required, instead of making multiple variables one array can be used which can store multiple values. Array stores data in sequential order. An example program to demonstrate the use of arrays in classes is shown below.


#include <iostream>

using namespace std;


class Shop

{

    int itemId[100];

    int itemPrice[100];

    int counter;


public:

    void initCounter(void) { counter = 0; }

    void setPrice(void);

    void displayPrice(void);

};


void Shop ::setPrice(void)

{

    cout << "Enter Id of your item no " << counter + 1 << endl;

    cin >> itemId[counter];

    cout << "Enter Price of your item" << endl;

    cin >> itemPrice[counter];

    counter++;

}


void Shop ::displayPrice(void)

{

    for (int i = 0; i < counter; i++)

    {

        cout << "The Price of item with Id " << itemId[i] << " is " << itemPrice[i] << endl;

    }

}


int main()

{

    Shop dukaan;

    dukaan.initCounter();

    dukaan.setPrice();

    dukaan.setPrice();

    dukaan.setPrice();

    dukaan.displayPrice();

    return 0;

}



Static Data Members in C++

When a static data member is created, there is only a single copy of the data member which is shared between all the objects of the class. As we have discussed in our previous lecture that if the data members are not static then every object has an individual copy of the data member and it is not shared.


Static Methods in C++

When a static method is created, they become independent of any object and class. Static methods can only access static data members and static methods. Static methods can only be accessed using the scope resolution operator. An example program is shown below to demonstrate static data members and static methods in C++

#include <iostream>
using namespace std;

class Employee
{
    int id;
    static int count;

public:
    void setData(void)
    {
        cout << "Enter the id" << endl;
        cin >> id;
        count++;
    }
    void getData(void)
    {
        cout << "The id of this employee is " << id << " and this is employee number " << count << endl;
    }

    static void getCount(void){
        // cout<<id; // throws an error
        cout<<"The value of count is "<<count<<endl;
    }
};

// Count is the static data member of class Employee
int Employee::count; // Default value is 0

int main()
{
    Employee harry, rohan, lovish;
    // harry.id = 1;
    // harry.count=1; // cannot do this as id and count are private

    harry.setData();
    harry.getData();
    Employee::getCount();

    rohan.setData();
    rohan.getData();
    Employee::getCount();

    lovish.setData();
    lovish.getData();
    Employee::getCount();

    return 0;
}



We have defined a static “getCount” function. This function will print the value of the variable count”. The main thing to note here is that “getCount” function is static, so if we try to access any data members or member functions which are not static the compiler will throw an error.



An array of Objects in C++

An array of objects is declared the same as any other data-type array.  An array of objects consists of class objects as its elements. If the array consists of class objects it is called an array of objects. An example program to demonstrate the concept of an array of objects is shown below


#include <iostream>

using namespace std;


class Employee

{

    int id;

    int salary;


public:

    void setId(void)

    {

        salary = 122;

        cout << "Enter the id of employee" << endl;

        cin >> id;

    }


    void getId(void)

    {

        cout << "The id of this employee is " << id << endl;

    }

};


int main()

{

    // Employee harry, rohan, lovish, shruti;

    // harry.setId();

    // harry.getId();

    Employee fb[4];

    for (int i = 0; i < 4; i++)

    {

        fb[i].setId();

        fb[i].getId();

    }


    return 0;

}





Passing Object as Function Argument

Objects can be passed as function arguments. This is useful when we want to assign the values of a passed object to the current object. An example program to demonstrate the concept of passing an object as a function argument is shown below.



#include<iostream>

using namespace std;


class complex{

    int a;

    int b;


    public: 

        void setData(int v1, int v2){

            a = v1;

            b = v2;

        }


        void setDataBySum(complex o1, complex o2){

            a = o1.a + o2.a;

            b = o1.b + o2.b;

        }


        void printNumber(){

            cout<<"Your complex number is "<<a<<" + "<<b<<"i"<<endl;

        }

};


int main(){

    complex c1, c2, c3;

    c1.setData(1, 2);

    c1.printNumber();


    c2.setData(3, 4);

    c2.printNumber();


    c3.setDataBySum(c1, c2);

    c3.printNumber();

    return 0;

}





Friend Function in C++

Friend functions are those functions that have the right to access the private data members of class even though they are not defined inside the class. It is necessary to write the prototype of the friend function. One main thing to note here is that if we have written the prototype for the friend function in the class it will not make that function a member of the class. An example program to demonstrate the concept of friend function is shown below.

Properties of Friend Function

  • Not in the scope of the class
  • Since it is not in the scope of the class, it cannot be called from the object of that class, for example, sumComplex() is invalid
  • A friend function can be invoked without the help of any object
  • Usually contain objects as arguments
  • Can be declared under the public or private access modifier, it will not make any difference
  • It cannot access the members directly by their names, it needs (object_name.member_name) to access any member.
#include<iostream>
using namespace std;

// 1 + 4i
// 5 + 8i
// -------
// 6 + 12i 
class Complex{
    int a, b;
    friend Complex sumComplex(Complex o1, Complex o2);
    public:
        void setNumber(int n1, int n2){
            a = n1;
            b = n2;
        }

        // Below line means that non member - sumComplex funtion is allowed to do anything with my private parts (members)
        void printNumber(){
            cout<<"Your number is "<<a<<" + "<<b<<"i"<<endl;
        }
};

Complex sumComplex(Complex o1, Complex o2){
    Complex o3;
    o3.setNumber((o1.a + o2.a), (o1.b+o2.b))
    ;
    return o3;
}

int main(){
    Complex c1, c2, sum;
    c1.setNumber(1, 4);
    c1.printNumber();

    c2.setNumber(5, 8);
    c2.printNumber();

    sum = sumComplex(c1, c2);
    sum.printNumber();

    return 0;
}




Member Friend Functions in C++

Friend functions are those functions that have the access to private members of the class in which they are declared. The main thing to note here is that only that function can access the member function which is made a friend of the other class. An example of the friend function is shown below.


class Complex

{

    int a, b;

    // Individually declaring functions as friends

    // friend int Calculator ::sumRealComplex(Complex, Complex);

    // friend int Calculator ::sumCompComplex(Complex, Complex);


    // Aliter: Declaring the entire calculator class as friend

    friend class Calculator;


public:

    void setNumber(int n1, int n2)

    {

        a = n1;

        b = n2;a

    }


    void printNumber()

    {

        cout << "Your number is " << a << " + " << b << "i" << endl;

    }

};


int Calculator ::sumRealComplex(Complex o1, Complex o2)

{

    return (o1.a + o2.a);

}


int Calculator ::sumCompComplex(Complex o1, Complex o2)

{

    return (o1.b + o2.b);

}



Friend Functions in C++

As we have already discussed in previous lectures friend functions are those functions that can access the private data members of the other class. An example program to demonstrate friend functions in C++ is shown below.


class Y;


class X{

    int data;

    public:

        void setValue(int value){

            data = value;

        }

    friend void add(X, Y);    

};


class Y{

    int num;

    public:

        void setValue(int value){

            num = value;

        }

    friend void add(X, Y);    


};


void add(X o1, Y o2){

    cout<<"Summing data of X and Y objects gives me "<< o1.data + o2.num;

}

int main(){
    X a1;
    a1.setValue(3);

    Y b1;
    b1.setValue(15);

    add(a1, b1);
    return 0;
}



class c2;

class c1{
    int val1;
    friend void exchange(c1 & , c2 &);
    public:
        void indata(int a){
            val1 = a;
        }

        void display(void){
            cout<< val1 <<endl;
        }
};

class c2{
    int val2;
    friend void exchange(c1 &, c2 &);
    public:
        void indata(int a){
            val2 = a;
        }

        void display(void){
            cout<< val2 <<endl;
        }
};

void exchange(c1 &x, c2 &y){
    int tmp = x.val1;
    x.val1 = y.val2;
    y.val2 = tmp;
}

int main(){
    c1 oc1;
    c2 oc2;

    oc1.indata(34);
    oc2.indata(67);
    exchange(oc1, oc2);

    cout<<"The value of c1 after exchanging becomes: ";
    oc1.display();
    cout<<"The value of c2 after exchanging becomes: ";
    oc2.display();
    
    return 0;
}



Constructors in C++

A constructor is a special member function with the same name as the class. The constructor doesn’t have a return type. Constructors are used to initialize the objects of its class. Constructors are automatically invoked whenever an object is created.

Important Characteristics of Constructors in C++

  • A constructor should be declared in the public section of the class
  • They are automatically invoked whenever the object is created
  • They cannot return values and do not have return types
  • It can have default arguments
  • We cannot refer to their address

Constructor Overloading in C++

Constructor overloading is a concept in which one class can have multiple constructors with different parameters. The main thing to note here is that the constructors will run according to the arguments for example if a program consists of 3 constructors with 0, 1, and 2 arguments, so if we pass 1 argument to the constructor the compiler will automatically run the constructor which is taking 1 argument. An example program to demonstrate the concept of Constructor overloading in C++ is shown below.



#include <iostream>

using namespace std;


class Complex

{

    int a, b;


public:

    Complex(){

        a = 0;

        b =0;

    }


    Complex(int x, int y)

    {

        a = x;

        b = y;

    }


    Complex(int x){

        a = x;

        b = 0;

    }


  


    void printNumber()

    {

        cout << "Your number is " << a << " + " << b << "i" << endl;

    }

};

int main()
{
    Complex c1(4, 6);
    c1.printNumber();

    Complex c2(5);
    c2.printNumber();

    Complex c3;
    c3.printNumber();
    return 0;
}




Constructors with Default Arguments in C++

Default arguments of the constructor are those which are provided in the constructor declaration. If the values are not provided when calling the constructor the constructor uses the default arguments automatically. An example program to demonstrate the concept default arguments in C++ is shown below.

#include<iostream>

using namespace std;


class Simple{

    int data1;

    int data2;

    int data3;


    public:

        Simple(int a, int b=9, int c=8){

            data1 = a;

            data2 = b;

            data3 = c;

        }


        void printData();


};


void Simple :: printData(){

    cout<<"The value of data1, data2 and data3 is "<<data1<<", "<< data2<<" and "<< data3<<endl;

}

int main(){
    Simple s(12, 13);
    s.printData();
    return 0;
}




The output for the following program is shown in figure 1.




Dynamic Initialization of Objects Using Constructors

The dynamic initialization of the object means that the object is initialized at the runtime.  Dynamic initialization of the object using a constructor is beneficial when the data is of different formats. An example program is shown below to demonstrate the concept of dynamic initialization of objects using constructors.


#include<iostream>

using namespace std;



class BankDeposit{

    int principal;

    int years;

    float interestRate;

    float returnValue;


    public:

        BankDeposit(){}

        BankDeposit(int p, int y, float r); // r can be a value like 0.04

        BankDeposit(int p, int y, int r); // r can be a value like 14

        void show();

};


BankDeposit :: BankDeposit(int p, int y, float r)

{

    principal = p;

    years = y;

    interestRate = r;

    returnValue = principal;

    for (int i = 0; i < y; i++)

    {

        returnValue = returnValue * (1+interestRate);

    }

}


BankDeposit :: BankDeposit(int p, int y, int r)

{

    principal = p;

    years = y;

    interestRate = float(r)/100;

    returnValue = principal;

    for (int i = 0; i < y; i++)

    {

        returnValue = returnValue * (1+interestRate);

    }

}


void BankDeposit :: show(){

    cout<<endl<<"Principal amount was "<<principal

        << ". Return value after "<<years

        << " years is "<<returnValue<<endl;

}

int main(){
    BankDeposit bd1, bd2, bd3;
    int p, y;
    float r;
    int R;
    
    
    cout<<"Enter the value of p y and r"<<endl;
    cin>>p>>y>>r;
    bd1 = BankDeposit(p, y, r);
    bd1.show();

    cout<<"Enter the value of p y and R"<<endl;
    cin>>p>>y>>R;
    bd2 = BankDeposit(p, y, R);
    bd2.show();
    return 0;
}

The output for the following program is shown in figure 1.



Copy Constructor in C++

A copy constructor is a type of constructor that creates a copy of another object. If we want one object to resemble another object we can use a copy constructor. If no copy constructor is written in the program compiler will supply its own copy constructor. An example program to demonstrate the concept of a Copy constructor in C++ is shown below.


#include<iostream>

using namespace std;



class Number{

    int a;

    public:

        Number(){

            a = 0;

        }


        Number(int num){

            a = num;

        }

        // When no copy constructor is found, compiler supplies its own copy constructor

        Number(Number &obj){

            cout<<"Copy constructor called!!!"<<endl;

            a = obj.a;

        }


        void display(){

            cout<<"The number for this object is "<< a <<endl;

        }

};


int main(){
    Number x, y, z(45), z2;
    x.display();
    y.display();
    z.display();

    Number z1(z); // Copy constructor invoked
    z1.display();

    z2 = z; // Copy constructor not called
    z2.display();

    Number z3 = z; // Copy constructor invoked
    z3.display();

    // z1 should exactly resemble z  or x or y

    return 0;
}

The output for the following program is shown in figure 1.


Destructor in C++

A destructor is a type of function which is called when the object is destroyed. Destructor never takes an argument nor does it return any value. An example program to demonstrate the concept of destructors in C++ is shown below.


#include<iostream>

using namespace std;


// Destructor never takes an argument nor does it return any value 

int count=0;


class num{

    public:

        num(){

            count++;

            cout<<"This is the time when constructor is called for object number"<<count<<endl;

        }


        ~num(){

            cout<<"This is the time when my destructor is called for object number"<<count<<endl;

            count--;

        }

};

int main(){
    cout<<"We are inside our main function"<<endl;
    cout<<"Creating first object n1"<<endl;
    num n1;
    {
        cout<<"Entering this block"<<endl;
        cout<<"Creating two more objects"<<endl;
        num n2, n3;
        cout<<"Exiting this block"<<endl;
    }
    cout<<"Back to main"<<endl;
    return 0;
}

The output for the following program is shown in figure 1.

Figure 1: Program Output



Inheritance in C++ an Overview

  • Reusability is a very important feature of OOPs
  • In C++ we can reuse a class and add additional features to it
  • Reusing classes saves time and money
  • Reusing already tested and debugged classes will save a lot of effort of developing and debugging the same thing again

What is Inheritance in C++?

  • The concept of reusability in C++ is supported using inheritance
  • We can reuse the properties of an existing class by inheriting it
  • The existing class is called a base class
  • The new class which is inherited from the base class is called a derived class
  • Reusing classes saves time and money
  • There are different types of inheritance in C++

Forms of Inheritance in C++

  • Single Inheritance
  • Multiple Inheritance
  • Hierarchical Inheritance
  • Multilevel Inheritance
  • Hybrid Inheritance

Single Inheritance in C++

Single inheritance is a type of inheritance in which a derived class is inherited with only one base class. For example, we have two classes “employee” and “programmer”. If the “programmer” class is inherited from the “employee” class which means that the “programmer” class can now implement the functionalities of the “employee” class.

Multiple Inheritances in C++

 Multiple inheritances are a type of inheritance in which one derived class is inherited with more than one base class. For example, we have three classes “employee”, “assistant” and “programmer”. If the “programmer” class is inherited from the “employee” and “assistant” class which means that the “programmer” class can now implement the functionalities of the “employee” and “assistant” class.

Hierarchical Inheritance

A hierarchical inheritance is a type of inheritance in which several derived classes are inherited from a single base class. For example, we have three classes “employee”, “manager” and “programmer”. If the “programmer” and “manager” classes are inherited from the “employee” class which means that the “programmer” and “manager” class can now implement the functionalities of the “employee” class.

Multilevel Inheritance in C++

Multilevel inheritance is a type of inheritance in which one derived class is inherited from another derived class. For example, we have three classes “animal”, “mammal” and “cow”. If the “mammal” class is inherited from the “animal” class and “cow” class is inherited from “mammal” which means that the “mammal” class can now implement the functionalities of “animal” and “cow” class can now implement the functionalities of “mammal” class.

Hybrid Inheritance in C++

Hybrid inheritance is a combination of multiple inheritance and multilevel inheritance. In hybrid inheritance, a class is derived from two classes as in multiple inheritances. However, one of the parent classes is not a base class. For example, we have four classes “animal”, “mammal”, “bird”, and “bat”. If “mammal”  and “bird” classes are inherited from the “animal” class and “bat” class is inherited from “mammal” and “bird” classes which means that “mammal” and “bird” classes can now implement the functionalities of “animal” class and “bat” class can now implement the functionalities of “mammal” and “bird” classes



Inheritance Syntax and Visibility mode in C++

Inheritance is a process of inheriting attributes of the base class by a derived class. The syntax of the derived class is shown below.

 // Derived Class syntax
class {{derived-class-name}} : {{visibility-mode}} {{base-class-name}}
{
    class members/methods/etc...
}

Code Snippet 1: Derived Class syntax


As shown in a code snippet 1,

  • After writing the class keyword we have to write the derived class name and then put a “:” sign.
  • After “:” sign we have to write the visibility mode and then write the base class name.

Note:

  • Default visibility mode is private
  • Public Visibility Mode: Public members of the base class becomes Public members of the derived class
  • Private Visibility Mode: Public members of the base class become private members of the derived class
  • Private members are never inherited

An example program is shown below to demonstrate the concept of inheritance.

#include <iostream>
using namespace std;

// Base Class
class Employee
{
public:
    int id;
    float salary;
    Employee(int inpId)
    {
        id = inpId;
        salary = 34.0;
    }
    Employee() {}
};

// Creating a Programmer class derived from Employee Base class
class Programmer : public Employee
{
public:
    int languageCode;
    Programmer(int inpId)
    {
        id = inpId;
        languageCode = 9;
    }
    void getData(){
        cout<<id<<endl;
    }
};

Code Snippet 2: Inheritance Example Program

The main program is shown in code snippet 3.

int main()
{
    Employee harry(1), rohan(2);
    cout << harry.salary << endl;
    cout << rohan.salary << endl;
    Programmer skillF(10);
    cout << skillF.languageCode<<endl;
    cout << skillF.id<<endl;
    skillF.getData();
    return 0;
}

Code Snippet 3: Main Program


The output for the following program is shown in figure 1.

Figure 1: Program Output


Single Inheritance in C++

Single inheritance is a type of inheritance in which a derived class is inherited with only one base class. For example, we have two classes “employee” and “programmer”. If the “programmer” class is inherited from the “employee” class which means that the “programmer” class can now implement the functionalities of the “employee” class.

An example program to demonstrate the concept of single inheritance in C++ is shown below.

class Base
{
    int data1; // private by default and is not inheritable
public:
    int data2;
    void setData();
    int getData1();
    int getData2();
};

void Base ::setData(void)
{
    data1 = 10;
    data2 = 20;
}

int Base::getData1()
{
    return data1;
}

int Base::getData2()
{
    return data2;
}

Code Snippet 1: Base Class


The derived class will inherit the base class which is shown below.

class Derived : public Base
{ // Class is being derived publically
    int data3;

public:
    void process();
    void display();
};

void Derived ::process()
{
    data3 = data2 * getData1();
}

void Derived ::display()
{
    cout << "Value of data 1 is " << getData1() << endl;
    cout << "Value of data 2 is " << data2 << endl;
    cout << "Value of data 3 is " << data3 << endl;
}

Code Snippet 2: Derived Class

The main program is shown in code snippet 3.

int main()
{
    Derived der;
    der.setData();
    der.process();
    der.display();

    return 0;
}

Code Snippet 3: Main Program

The output for the following program is shown in figure 1.

Figure 1: Program Output 




Protected Access Modifiers in C++

Protected access modifiers are similar to the private access modifiers but protected access modifiers can be accessed in the derived class whereas private access modifiers cannot be accessed in the derived class. A table is shown below which shows the behavior of access modifiers when they are derived “public”, “private”, and “protected”.

 Public Derivation      Private Derivation    Protected Derivation
Private members           Not Inherited              Not Inherited              Not Inherited              
Protected members           Protected                    Private                         Protected                    
Public members           PublicPrivate                         Protected                    





Multilevel Inheritance in C++

Multilevel inheritance is a type of inheritance in which one derived class is inherited from another derived class. For example, we have three classes “animal”, “mammal” and “cow”. If the “mammal” class is inherited from the “animal” class and “cow” class is inherited from “mammal” which means that the “mammal” class can now implement the functionalities of “animal” and “cow” class can now implement the functionalities of “mammal” class.

An example program is shown below to demonstrate the concept of multilevel inheritance in C++.

#include <iostream>
using namespace std;

class Student
{
protected:
    int roll_number;

public:
    void set_roll_number(int);
    void get_roll_number(void);
};

void Student ::set_roll_number(int r)
{
    roll_number = r;
}

void Student ::get_roll_number()
{
    cout << "The roll number is " << roll_number << endl;
}

Code Snippet 1: Student Class

The code for the “exam” class is shown below which is inheriting the “student” class

class Exam : public Student
{
protected:
    float maths;
    float physics;

public:
    void set_marks(float, float);
    void get_marks(void);
};

void Exam ::set_marks(float m1, float m2)
{
    maths = m1;
    physics = m2;
}

void Exam ::get_marks()
{
    cout << "The marks obtained in maths are: " << maths << endl;
    cout << "The marks obtained in physics are: " << physics << endl;
}

Code Snippet 2: Exam Class



The code for the “result” class is shown below which is inheriting the “exam” class

class Result : public Exam
{
    float percentage;

public:
    void display_results()
    {
        get_roll_number();
        get_marks();
        cout << "Your result is " << (maths + physics) / 2 << "%" << endl;
    }
};

Code Snippet 3: Result Class


int main()
{
    Result harry;
    harry.set_roll_number(420);
    harry.set_marks(94.0, 90.0);
    harry.display_results();
    return 0;
}

Code Snippet 4: Main Program

The output for the following program is shown in figure 1.



An example program is shown below to demonstrate the concept of multiple inheritances in C++.

class Base1{
protected:
    int base1int;

public:
    void set_base1int(int a)
    {
        base1int = a;
    }
};

class Base2{
protected:
    int base2int;

public:
    void set_base2int(int a)
    {
        base2int = a;
    }
};

class Base3{
protected:
    int base3int;

public:
    void set_base3int(int a)
    {
        base3int = a;
    }
};

Code Snippet 2: Base Classes


The code for the “Derived” class is shown below. “Derived” class will inherit all the base classes.

class Derived : public Base1, public Base2, public Base3
{
    public: 
        void show(){
            cout << "The value of Base1 is " << base1int<<endl;
            cout << "The value of Base2 is " << base2int<<endl;
            cout << "The value of Base3 is " << base3int<<endl;
            cout << "The sum of these values is " << base1int + base2int + base3int << endl;
        }
};

Code Snippet 3: Derived Class


It can be clearly seen that the class “Derived” is inheriting class “Base1”, “Base2”, and “Base3”. This is an example of multiple inheritances. The code main program is shown below.

int main()
{
    Derived harry;
    harry.set_base1int(25);
    harry.set_base2int(5);
    harry.set_base3int(15);
    harry.show();
    
    return 0;
}

Code Snippet 4: Main Program

The output for the following program is shown in figure 1.

Figure 1: Program Output

Ambiguity Resolution in Inheritance

Ambiguity in inheritance can be defined as when one class is derived for two or more base classes then there are chances that the base classes have functions with the same name. So it will confuse derived class to choose from similar name functions. To solve this ambiguity scope resolution operator is used “::”. An example program is shown below to demonstrate the concept of ambiguity resolution in inheritance.

class Base1{
    public:
        void greet(){
            cout<<"How are you?"<<endl;
        }
};

class Base2{
    public:
        void greet()
        {
            cout << "Kaise ho?" << endl;
        }
};


class Derived : public Base1, public Base2{
   int a;
   public:
    void greet(){
        Base2 :: greet();
    }
};

Code Snippet 1: Ambiguity Resolution in Inheritance Example Program 1



  1. We have created a “Derived” class which is inheriting “Base1” and “Base2” classes. The “Derived” class consists of public member function “greet”. The function “greet” will run the “greet” function of the “Base2” class because we have used a scope resolution operator to let the compiler know which function should it run otherwise it will cause ambiguity.

The code of the main function is shown below

int main(){
  // Ambibuity 1
     Base1 base1obj;
     Base2 base2obj;
     base1obj.greet();
     base2obj.greet();
     Derived d;
     d.greet();

    return 0;
}

Code Snippet 2: Main program 1






Another example of ambiguity resolution in inheritance is shown below.

class B{
    public:
        void say(){
            cout<<"Hello world"<<endl;
        }
};

class D: public B{
    int a;
    // D's new say() method will override base class's say() method
    public:
        void say()
        {
            cout << "Hello my beautiful people" << endl;
        }
};

Code Snippet 3:  Ambiguity Resolution in Inheritance Example Program 2


The code of the main function is shown below,

int main(){
    // Ambibuity 2
    B b;
    b.say();

    D d;
    d.say();

    return 0;
}

Code Snippet 4: Main Program 2




Virtual Base Class in C++

The virtual base class is a concept used in multiple inheritances to prevent ambiguity between multiple instances. For example: suppose we created a class “A” and two classes “B” and “C”, are being derived from class “A”. But once we create a class “D” which is being derived from class “B” and “C” as shown in figure 1.

Figure 1: Virtual Base Class Example Diagram


  1. Class “A” is a parent class of two classes “B” and “C”
  2. And both “B” and “C” classes are the parent of class “D”

The main thing to note here is that the data members and member functions of class “A” will be inherited twice in class “D” because class “B” and “C” are the parent classes of class “D” and they both are being derived from class “A”.

So when the class “D” will try to access the data member or member function of class “A” it will cause ambiguity for the compiler and the compiler will throw an error. To solve this ambiguity we will make class “A” as a virtual base class. To make a virtual base class “virtual” keyword is used.

When one class is made virtual then only one copy of its data member and member function is passed to the classes inheriting it. So in our example when we will make class “A” a virtual class then only one copy of the data member and member function will be passed to the classes “B” and “C” which will be shared between all classes. This will help to solve the ambiguity.


The syntax of the virtual base class is shown in the code snippet below,

#include <iostream> 
using namespace std; 
class A { 
public: 
    void say() 
    { 
        cout << "Hello world"<<endl; 
    } 
}; 
class B : public virtual A { 
};   
class C : public virtual A { 
};   
class D : public B, public C { 
}; 

Code Snippet 1: Virtual Base Class Syntax Example Code

#include<iostream>
using namespace std;

class Student{
    protected:
        int roll_no;
    public:
        void set_number(int a){
            roll_no = a;
        }
        void print_number(void){
            cout<<"Your roll no is "<< roll_no<<endl;
        }
};

class Test : virtual public Student{
    protected:
        float maths, physics;
        public:
            void set_marks(float m1, float m2){
                maths = m1;
                physics = m2;
            }

            void print_marks(void){
                cout << "You result is here: "<<endl
                     << "Maths: "<< maths<<endl
                     << "Physics: "<< physics<<endl;
            }
};

class Sports: virtual public Student{
    protected:
        float score;
    public:
        void set_score(float sc){
            score = sc;
        }

        void print_score(void){
            cout<<"Your PT score is "<<score<<endl;
        }

};

class Result : public Test, public Sports{
    private:
        float total;
    public:
        void display(void){
            total = maths + physics + score;
            print_number();
            print_marks();
            print_score();
            cout<< "Your total score is: "<<total<<endl;
        }
};
int main(){
    Result harry;
    harry.set_number(4200);
    harry.set_marks(78.9, 99.5);
    harry.set_score(9);
    harry.display();
    return 0;
}


  1. Class “Student” is a parent class of two classes “Test” and “Sports”
  2. And both “Test” and “Sports” classes are the parent of class “Result”

The main thing to note here is that the data members and member functions of class “Student” will be inherited twice in class “Result” because class “Test” and “Sports” are the parent classes of class “Result” and they both are being derived from class “Student”.

So when the class “Result” will try to access the data member or member function of class “Student” it will cause ambiguity for the compiler and the compiler will throw an error. To solve this ambiguity we will make class “Student” as a virtual base class. To make a virtual base class “virtual” keyword is used.

When one class is made virtual then only one copy of its data member and member function is passed to the classes inheriting it. So in our example when we will make class “Student” a virtual class then only one copy of data member and member function will be passed to the classes “Test” and “Sports” which will be shared between all classes. This will help to solve the ambiguity.

An example program of the following diagram is shown in a code snippet above.




As I have given you an exercise on inheritance to solve in the previous tutorial. In this tutorial, we will see the solution to that exercise. So the question was to make three classes “SimpleCalculator”, “ScientificCalculator” and “HybridCalculator”.

  • In “SimpleCalculator” class you have to take input of 2 numbers and perform function (+, -, *, /)
  • In “ScientificCalculator” class you have to take input of 2 numbers and perform any 4 scientific operations
  • You have to inherit both “SimpleCalculator” and “ScientificCalculator” classes with the “HybridCalculator” class. You have to make an object of the “HybridCalculator” class and display the results of “SimpleCalculator” and “ScientificCalculator” classes.

The solution to the above Question is shown below,

class SimpleCalculator {
    int a, b;
    public:
        void getDataSimple()
        {
            cout<<"Enter the value of a"<<endl;
            cin>>a;
            cout<<"Enter the value of b"<<endl;
            cin>>b;
        }

        void performOperationsSimple(){
            cout<<"The value of a + b is: "<<a + b<<endl;
            cout<<"The value of a - b is: "<<a - b<<endl;
            cout<<"The value of a * b is: "<<a * b<<endl;
            cout<<"The value of a / b is: "<<a / b<<endl;
        }
};

Code snippet 1: Simple Calculator Class




class ScientificCalculator{
    int a, b;

    public:
        void getDataScientific()
        {
            cout << "Enter the value of a" << endl;
            cin >> a;
            cout << "Enter the value of b" << endl;
            cin >> b;
        }

        void performOperationsScientific()
        { 
            cout << "The value of cos(a) is: " << cos(a) << endl;
            cout << "The value of sin(a) is: " << sin(a) << endl;
            cout << "The value of exp(a) is: " << exp(a) << endl;
            cout << "The value of tan(a) is: " << tan(a) << endl;
        }
};

Code Snippet 2: Scientific Calculator Class

class HybridCalculator : public SimpleCalculator, public ScientificCalculator{
    
};

Code Snippet 3: Hybrid Calculator Class

int main()
{
    HybridCalculator calc;
    calc.getDataScientific();
    calc.performOperationsScientific();
    calc.getDataSimple();
    calc.performOperationsSimple();
    
    return 0;
}

Code Snippet 4: Main Program



Constructors in Derived Class in C++

  • We can use constructors in derived classes in C++
  • If the base class constructor does not have any arguments, there is no need for any constructor in the derived class
  • But if there are one or more arguments in the base class constructor, derived class need to pass argument to the base class constructor
  • If both base and derived classes have constructors, base class constructor is executed first

Constructors in Multiple Inheritances

  • In multiple inheritances, base classes are constructed in the order in which they appear in the class deceleration. For example if there are three classes “A”, “B”, and “C”, and the class “C” is inheriting classes “A” and “B”. If the class “A” is written before class “B” then the constructor of class “A” will be executed first. But if the class “B” is written before class “A” then the constructor of class “B” will be executed first.
  • In multilevel inheritance, the constructors are executed in the order of inheritance. For example if there are three classes “A”, “B”, and “C”, and the class “B” is inheriting classes “A” and the class “C” is inheriting classes “B”. Then the constructor will run according to the order of inheritance such as the constructor of class “A” will be called first then the constructor of class “B” will be called and at the end constructor of class “C” will be called.

Special Syntax

  • C++ supports a special syntax for passing arguments to multiple base classes
  • The constructor of the derived class receives all the arguments at once and then will pass the call to the respective base classes
  • The body is called after the constructors is finished executing

Syntax Example:

Derived-Constructor (arg1, arg2, arg3….): Base 1-Constructor (arg1,arg2), Base 2-Constructor(arg3,arg4)
{.
} Base 1-Constructor (arg1,arg2)

Special Case of Virtual Base Class

  • The constructors for virtual base classes are invoked before a non-virtual base class
  • If there are multiple virtual base classes, they are invoked in the order declared
  • Any non-virtual base class are then constructed before the derived class constructor is executed

Constructors in Derived Class in C++

As we have discussed before about the constructors in derived class in a code snippet below three cases are given to clarify the execution of constructors.

/*
Case1:
class B: public A{
   // Order of execution of constructor -> first A() then B()
};

Case2:
class A: public B, public C{
    // Order of execution of constructor -> B() then C() and A()
};

Case3:
class A: public B, virtual public C{
    // Order of execution of constructor -> C() then B() and A()
};

*/

Code Snippet 1: Constructors Execution Example Cases


To demonstrate the concept of constructors in derived classes an example program is shown below.

class Base1{
    int data1;
    public:
        Base1(int i){
            data1 = i;
            cout<<"Base1 class constructor called"<<endl;
        }
        void printDataBase1(void){
            cout<<"The value of data1 is "<<data1<<endl;
        }
};

class Base2{
    int data2;

    public:
        Base2(int i){
            data2 = i;
            cout << "Base2 class constructor called" << endl;
        }
        void printDataBase2(void){
            cout << "The value of data2 is " << data2 << endl;
        }
};

class Derived: public Base2, public Base1{
    int derived1, derived2;
    public:
        Derived(int a, int b, int c, int d) : Base2(b), Base1(a)
        {
            derived1 = c;
            derived2 = d;
            cout<< "Derived class constructor called"<<endl;
        }
        void printDataDerived(void)
        {
            cout << "The value of derived1 is " << derived1 << endl;
            cout << "The value of derived2 is " << derived2 << endl;
        }
};

Code Snippet 2: Constructors in Derived Class Example Program


int main(){
    Derived harry(1, 2, 3, 4);
    harry.printDataBase1();
    harry.printDataBase2();
    harry.printDataDerived();
    return 0;
}

Code Snippet 3: Main Program


Initialization list in Constructors in C++

The initialization list in constructors is another concept of initializing the data members of the class. The syntax of the initialization list in constructors is shown below.

/*
Syntax for initialization list in constructor:
constructor (argument-list) : initilization-section
{
    assignment + other code;
}

Code Snippet 1: Initialization list in Constructors Syntax


To demonstrate the concept of Initialization list in Constructors an example program is shown below,

class Test
{
    int a;
    int b;

public:
    Test(int i, int j) : a(i), b(j)
    {
        cout << "Constructor executed"<<endl;
        cout << "Value of a is "<<a<<endl;
        cout << "Value of b is "<<b<<endl;
    }
};

int main()
{
    Test t(4, 6);

    return 0;
}

Code Snippet 2: Initialization list in Constructors Example Program 1

Main Points

The main thing to note here is that if we use the code shown below to initialize data members the compiler will throw an error because the data member “a” is being initialized first and the “b” is being initialized second so we have to assign the value to “a” data member first.

Test(int i, int j) : b(j), a(i+b)

Code Snippet 3: Initialization list in Constructors Example 1

But if we use the code shown below to initialize data members the compiler will not throw an error because the data member “a” is being initialized first and we are assigning the value to the data member “a” first.

Test(int i, int j) : a(i), b(a + j)

Code Snippet 4: Initialization list in Constructors Example 2



Comments

Popular posts from this blog

Amount Vs Word

Day vs Dates

FIRST REPEATING ELEMENT