Download Object oriented programming using c++ full notes and more Slides Object Oriented Programming in PDF only on Docsity! UNIT-1 Introduction to OOPS and C++ elements Introduction to OOPs, Features & Advantages of OOPs, Different element of C++ (Tokens, Keywords, Identifiers, Variable, Constant, Operators, Expression, String). C++ OOPs Concepts bject-oriented programming has a sweeping impact because it appeals at multiple levels and promises faster and cheaper development and maintenance. It follows a bottom-up approach to develop applications. In this section, we will discuss in-depth what is object-oriented programming? Object-Oriented Programming The word object-oriented is the combination of two words i.e. object and oriented. The dictionary meaning of the object is an article or entity that exists in the real world. The meaning of oriented is interested in a particular kind of thing or entity. In layman's terms, it is a programming pattern that rounds around an object or entity are called object-oriented programming. The technical definition of object-oriented programming is as follows: The object-oriented programming is basically a computer programming design philosophy or methodology that organizes/ models software design around data, or objects rather than functions and logic. An object is referred to as a data field that has unique attributes and behavior. Everything in OOP is grouped as self-sustainable objects. It is the most popular programming model among developers. It is well suited for programs that are large, complex, and actively updated or maintained. It simplifies software development and maintenance by providing major concepts such as abstraction, inheritance, polymorphism, and encapsulation. These core concepts support OOP. A real-world example of OOP is the automobile. It more completely illustrates the power of object-oriented design. . Pillars of OOPs The major concepts that we have discussed above are known as pillars of OOPs. There are four pillars on which OOP rests. Abstraction Encapsulation Inheritance Polymorphism Let's discuss each in detail. Abstraction The concept allows us to hide the implementation from the user but shows only essential information to the user. Using the concept developer can easily make changes and added over time. OOPs Concepts The OOPs concepts include the following: 1. Object 2. Class 3. Inheritance 4. Polymorphism 5. Abstraction 6. Encapsulation Object An object is a real-world entity that has attributes, behavior, and properties. It is referred to as an instance of the class. It contains member functions, variables that we have defined in the class. It occupies space in the memory. Different objects have different states or attributes, and behaviors. Class A class is a blueprint or template of an object. It is a user-defined data type. Inside a class, we define variables, constants, member functions, and other functionality. it binds data and functions together in a single unit. It does not consume memory at run time. Note that classes are not considered as a data structure. It is a logical entity. It is the best example of data binding. Note that a class can exist without an object but vice-versa is not possible. The following figure best illustrates the class and object in OOP. Apart from these core concepts, there are some other object-oriented concepts used in OOP. Coupling In programming, separation of concerns is known as coupling. It means that an object cannot directly change or modify the state or behavior of other objects. It defines how closely two objects are connected together. There are two types of coupling, loose coupling, and tight coupling. Objects that are independent of one another and do not directly modify the state of other objects is called loosely coupled. Loose coupling makes the code more flexible, changeable, and easier to work with. Objects that depend on other objects and can modify the states of other objects are called tightly coupled. It creates conditions where modifying the code of one object also requires changing the code of other objects. The reuse of code is difficult in tight coupling because we cannot separate the code. Since using loose coupling is always a good habit. Cohesion In OOP, cohesion refers to the degree to which the elements inside a module belong together. It measures the strength of the relationship between the module and data. In short, cohesion represents the clarity of the responsibilities of a module. It is often contrasted with coupling. It focuses on a how single module or class is intended. Higher the cohesiveness of the module or class, better is the object-oriented design. There are two types of cohesion, i.e. High and Low. High cohesion is associated with several required qualities of software including robustness, reliability, and understandability. Low cohesion is associated with unwanted qualities such as being difficult to maintain, test, reuse, or even understand. High cohesion often associates with loose coupling and vice versa. Composition Composition is one of the vital concepts in OOP. It describes a class that references one or more objects of other classes in instance variables. It allows us to model a has-a association between objects. We can find such relationships in the real world. For example, a car has an engine. the following figure depicts the same OOP code is difficult to understand if you do not have the corresponding class documentation. In certain scenarios, these programs can consume a large amount of memory. Not suitable for small problems. Takes more time to solve problems. List of Object-Oriented Programming Languages There are various object-oriented programming languages are present. But we have enlisted some popular and widely used OOP languages. According to the TIOBE index, the top twenty OOP languages are Java, C++, C#, Python, R, PHP, Visual Basic.NET, JavaScript, Ruby, Perl, Object Pascal, Objective-C, Dart, Swift, Scala, Kotlin, Common Lisp, MATLAB, and Smalltalk. Applications of OOPs Computer graphics applications Object-oriented database User-interface design such as windows Real-time systems Simulation and modeling Client-Server System Artificial Intelligence System CAD/CAM Software Office automation system Difference between Tokens, Identifiers, and Keywords in C++ In this article, we will discuss the difference between the Tokens, Identifiers, and Keywords in C++. But before discussing their differences, we must know about the Tokens, Identifiers, and Keywords in C++ with their types and characteristics. What are Tokens? Tokens are the smallest individual pieces of a C++ program, serving as the syntax's building blocks. They are fundamental parts that the compiler recognizes and that define the structure and logic of a C++ codebase. Tokens are divided into several sorts, each with its role in program execution. Types of Tokens: Tokens in C++ are classified into numerous types: Keywords: Keywords are predefined reserved terms in the C++ language that have unique meanings and functionalities. These terms have distinct meanings and cannot be altered or used as identifiers. Among the keywords in C++ are if, else, for, while, int, class, and return. They serve as the language's foundation, defining its core control structures and data types. Identifiers: Variables, functions, classes, and user-defined entities all have identifiers. The programmer creates these names, which serve as references to memory regions, allowing manipulation and interaction within the program. Identifiers adhere to certain guidelines: They can be characters (both uppercase and lowercase), numbers, or underscores. Identifiers must begin with a letter or a period. They should not be confused with keywords. In C++, identifiers are case-sensitive. Constants: In C++, constants are fixed values that do not change during program execution. Integer constants, floating-point constants, character constants, and string literals are some examples. 1. const int MAX_COUNT = 100; // 'MAX_COUNT' is a constant token with a value of 10 0 Operators: Operators are symbols in C++ that perform specified operations on operands. Arithmetic operators (+, -, *, /), relational operators (, >, ==,!=), logical operators (&&, ||,!), assignment operators (=, +=, -=), and others are examples. Operators assist in the execution of various computations and comparisons within a program. Seperators and Delimiters: Separators and delimiters are characters that are used to structure and separate various elements of the program. Braces, parentheses (), commas, semicolons; and other symbols are examples. They aid in the organization of code blocks and the definition of program grammar. Literals: Literals are explicit values that are utilized in the program. Numeric literals (integer or floating-point numbers), character literals (single characters enclosed in single quotes''), and string literals (sequences of characters encased in double quotations " ") are examples. Tokens' Function in C++: Tokens are the fundamental parts that make up the syntax of C++ programs. They are the units analysed, processed, and translated into machine-readable instructions by the compiler. Understanding the various token types and their functions is critical for building reliable and efficient C++ code. For example, a line of code like int x = 10; has many tokens: int: It is a keyword that indicates the data type. x: It is an identifier that represents the variable name. =: It is the assignment operator. 10: It is an integer literal containing the initial value of variable x. ; The semicolon acts as a statement terminator. What are Identifiers? Identifiers are names for various parts of a C++ program in the programming world. They are user-defined tokens that can be used to represent variables, functions, classes, constants, labels, and user-defined types. Identifiers are extremely important in making code legible, comprehensible, and maintainable. Characteristics of Identifiers: There are several characteristics of the identifiers. Some main characteristics of the identifiers are as follows: Identifiers can include letters (both uppercase and lowercase), numerals, and underscores (_). However, they must adhere to the following guidelines: 1. They must not begin with a digit. 2. Spaces and special characters, such as @, $, %,, are not permitted in identifiers. 3. Because C++ is case-sensitive, uppercase and lowercase letters are separate. 4. For example, myVariable, MyVariable, and MYVARIABLE are all distinct identifiers. Reserved Keywords: Identifiers and C++ keywords or reserved words that cannot be the same. Keywords are established keywords within a language that are used for certain purposes. For example, identifiers cannot be named int, class, if, while, and so on since these words have specified meanings in C++. Meaningful and Descriptive: Choosing meaningful and descriptive identifiers is a smart practice. This activity aids in understanding the purpose of variables, functions, and other code components. For example, having totalAmount as an identifier for a variable that represents the total amount is more informative than having a general term like temp. Types of Identifiers: 2. int main() { 3. // Keywords in C++ 4. int number = 10; // 'int' is a keyword, 'number' is an identifier 5. if (number == 10) { // 'if' is a keyword 6. std::cout << "The number is 10." << std::endl; // 'std::cout', '<<', 'endl' are tokens 7. } else { 8. std::cout << "The number is not 10." << std::endl; 9. } 10. // Identifiers in C++ 11. int a = 5; // 'a' is an identifier 12. float b = 3.14; // 'b' is an identifier 13. char c = 'A'; // 'c' is an identifier 14. // Tokens in C++ 15. const double PI = 3.14159; // 'const', 'double', 'PI', '=', '3.14159', ';' are tokens 16. std::string message = "Hello, World!"; // 'std', '::', 'string', 'message', '=', '"Hello, World! "', ';' are tokens 17. return 0; 18. } 19. Output: 20. The number is 10. 21. Example 2: 22. Let us take another example to demonstrate Tokens, Keywords, and Identifiers in C++: 23. #include <iostream> 24. #include <string> 25. using namespace std; 26. int main() { 27. // Keywords 28. int num = 5; 29. string name = "John"; 30. // Identifiers 31. int total Output: Differences between Tokens, Identifiers, and Keywords in C++: There are several difference between tokens, identifiers, and keywords in C++. Some main differences are as follows: Aspect Tokens Identifiers Keywords Definition It is the smallest individual unit in C++ syntax. User-defined names for program elements These are predefined reserved words in C++. Roles These are used to define the structure and logic of a C++ codebase. It represents variables, functions, and classes. These are used to define specific functionalities in code. Examples if, int, =, ; , +, 123, etc. variableName, functionName, className if, else, for, int, return, etc. Types Keywords, operators, literals, etc. User-created names. Reserved words with specific meanings. Categories Keywords are a subset of tokens. Identifiers are a type of token. Keywords are a distinct token category. Purpose Define language syntax and semantics. Represent entities within the program Reserved for specific language purposes Usage Construct statements and expressions Refer to memory locations. Define control flow, data types, etc. Cannot be used It cannot be redefined or modified. It can be created by the programmer. It cannot be used as user- defined names. UNIT-2 Program Control Statements Sequential Constructs, Decision Making Construct, Iteration / Loop Construct, Arrays, Functions (User defined Function, Inline Function, Function Overloading), User Defined Data Types (Structure, Union and Enumeration). C++ Data Types A data type specifies the type of data that a variable can store such as integer, floating, character etc. There are 4 types of data types in C++ language. Types Data Types Basic Data Type int, char, float, double, etc Derived Data Type array, pointer, etc Enumeration Data Type enum User Defined Data Type structure store derived data types like structures, pointers, and other data types, which is an addition. The array representation in a picture is provided below. Advantages of C++ Array Code Optimization (less code) Random Access Easy to traverse data Easy to manipulate data Easy to sort data etc. Disadvantages of C++ Array Fixed size C++ Array Types There are 2 types of arrays in C++ programming: 1. Single Dimensional Array 2. Multidimensional Array C++ Single Dimensional Array Let's see a simple example of C++ array, where we are going to create, initialize and traverse array. 1. #include <iostream> 2. using namespace std; 3. int main() 4. { 5. int arr[5]={10, 0, 20, 0, 30}; //creating and initializing array 6. //traversing array 7. for (int i = 0; i < 5; i++) 8. { 9. cout<<arr[i]<<"\n"; 10. } 11. } Output: 10 0 20 0 30 C++ Array Example: Traversal using foreach loop We can also traverse the array elements using foreach loop. It returns array element one by one. 1. #include <iostream> 2. using namespace std; 3. int main() 4. { 5. int arr[5]={10, 0, 20, 0, 30}; //creating and initializing array 6. //traversing array 7. for (int i: arr) 8. { 9. cout<<i<<"\n"; 10. } 11. } Output: 10 20 30 40 50 Why do we need arrays? With a limited number of objects, we can use regular variables (v1, v2, v3,..), but when we need to hold many instances, managing them with normal variables becomes challenging. To represent numerous instances in one variable, we use an array. What happens if we try to access out of bound array? The array's elements will be numbered 0 through 9 if we define an array of size 10. We will have Undefined Behaviour if we attempt to access an element at an index higher than 10, though. C++ array with empty members The maximum number of elements that can be stored in an array in C++ is n. What will happen, though, if we store fewer than n elements? For example, 1. // store only 3 elements in the array 2. int x[6] = {19, 10, 8}; The array x in this case is 6 elements wide. But we've only given it a three-element initialization. When that happens, the compiler fills in the empty spaces with random values. This random value frequently appears as 0. Important things to remember while using arrays in C++ 1. The array's indexes begin at 0. Meaning that the first item saved at index 0 is x[0]. 2. The final element of an array with size n is kept at index (n-1). This example's final element is x[5]. 3. An array's elements have sequential addresses. Consider the scenario where x[0beginning ]'s address is 2120. The address of the subsequent element, x[1], will then be 2124, followed by x[2], 2128, and so forth. Each element in this case has a four-fold increase in size. This is due to the fact that int has a 4 byte capacity. What is two-dimensional array? Each element in this kind of array is described by two indexes, the first of which denotes a row and the second of which denotes a column. As you can see, the components are arranged in a two-dimensional array using rows and columns; there are I number of rows and j number of columns. What is a multi-dimensional array? A two-dimensional array is the most basic type of multidimensional array; it also qualifies as a multidimensional array. There are no restrictions on the array's dimensions. How to insert it in array? 1. int mark[5] = {19, 10, 8, 17, 9} 2. // change 4th element to 9 3. mark[3] = 9; 4. // take input from the user 5. // store the value at third position 6. cin >> mark[2]; 7. // take input from the user 8. // insert at ith position 9. cin >> mark[i-1]; 10. 11. // print first element of the array 12. cout << mark[0]; Types of Functions There are two types of functions in C programming: 1. Library Functions: are the functions which are declared in the C++ header files such as ceil(x), cos(x), exp(x), etc. 2. User-defined functions: are the functions which are created by the C++ programmer, so that he/she can use it many times. It reduces complexity of a big program and optimizes the code. Declaration of a function The syntax of creating function in C++ language is given below: 1. return_type function_name(data_type parameter...) 2. { 3. //code to be executed 4. } C++ Function Example Let's see the simple example of C++ function. 1. #include <iostream> 2. using namespace std; 3. void func() { 4. static int i=0; //static variable 5. int j=0; //local variable 6. i++; 7. j++; 8. cout<<"i=" << i<<" and j=" <<j<<endl; 9. } 10. int main() 11. { 12. func(); 13. func(); 14. func(); 15. } Output: i= 1 and j= 1 i= 2 and j= 1 i= 3 and j= 1 Inline function in C++ One of the key features of C++ is the inline function. Therefore, let's first examine the utilization of inline functions and their intended application. If make a function is inline, then the compiler replaces the function calling location with the definition of the inline function at compile time. Any changes made to an inline function will require the inline function to be recompiled again because the compiler would need to replace all the code with a new code; otherwise, it will execute the old functionality. In brief, When the program executes a function call instruction, the CPU copies the function's arguments to the stack, caches the memory address of the next instruction and then hands control to the targeted function. The CPU then performs the function's code, saves the return value in a designated memory address or register, and hands control back to the function that is called the function. This may become overhead if the function's execution time is shorter than the time required to move from the calling function to the called function (callee). The overhead of the function call is typically negligible compared to the length of time required to run large or complicated functions. The time needed to call a small, frequently used function, however, is often far longer than the time necessary to run the function's code. Due to the fact that their execution time is less than switching time, tiny functions experience this overhead. To minimize the overhead of function calls, C++ offers inline functions. When a function is invoked, it expands in line and is known as an inline function. When an inline function is invoked, its entire body of code is added or replaced at the inline function call location. At compile time, the C++ compiler makes this substitution. Efficiency may be increased by inline function if it is tiny. To the compiler, inlining is merely a request; it is not a command. The compiler may reject the inlining request. The compiler may not implement inlining in situations like these: 1. If a function contains a loop. (for, while, do-while) 2. if a function has static variables. 3. Whether a function recurses. 4. If the return statement is absent from the function body and the return type of the function is not void. 5. Whether a function uses a goto or switch statement. Syntax for an inline function: 1. inline return_type function_name(parameters) 2. { 3. // function code? 4. } Let's understand the difference between the normal function and the inline function. Inside the main() method, when the function fun1() is called, the control is transferred to the definition of the called function. The addresses from where the function is called and the definition of the function are different. This control transfer takes a lot of time and increases the overhead. When the inline function is encountered, then the definition of the function is copied to it. In this case, there is no control transfer which saves a lot of time and also decreases the overhead. C++ Overloading (Function and Operator) If we create two or more members having the same name but different in number or type of parameter, it is known as C++ overloading. In C++, we can overload: methods, constructors, and indexed properties It is because these members have parameters only. Types of overloading in C++ are: Function overloading Operator overloading C++ Function Overloading Function Overloading is defined as the process of having two or more function with the same name, but different in parameters is known as function overloading in C++. In function overloading, the function is redefined by using either different types of arguments or a different 4. void fun(float); 5. void fun(int i) 6. { 7. std::cout << "Value of i is : " <<i<< std::endl; 8. } 9. void fun(float j) 10. { 11. std::cout << "Value of j is : " <<j<< std::endl; 12. } 13. int main() 14. { 15. fun(12); 16. fun(1.2); 17. return 0; 18. } The above example shows an error "call of overloaded 'fun(double)' is ambiguous". The fun(10) will call the first function. The fun(1.2) calls the second function according to our prediction. But, this does not refer to any function as in C++, all the floating point constants are treated as double not as a float. If we replace float to double, the program works. Therefore, this is a type conversion from float to double. Function with Default Arguments Let's see a simple example. 1. #include<iostream> 2. using namespace std; 3. void fun(int); 4. void fun(int,int); 5. void fun(int i) 6. { 7. std::cout << "Value of i is : " <<i<< std::endl; 8. } 9. void fun(int a,int b=9) 10. { 11. std::cout << "Value of a is : " <<a<< std::endl; 12. std::cout << "Value of b is : " <<b<< std::endl; 13. } 14. int main() 15. { 16. fun(12); 17. 18. return 0; 19. } The above example shows an error "call of overloaded 'fun(int)' is ambiguous". The fun(int a, int b=9) can be called in two ways: first is by calling the function with one argument, i.e., fun(12) and another way is calling the function with two arguments, i.e., fun(4,5). The fun(int i) function is invoked with one argument. Therefore, the compiler could not be able to select among fun(int i) and fun(int a,int b=9). Function with pass by reference Let's see a simple example. 1. #include <iostream> 2. using namespace std; 3. void fun(int); 4. void fun(int &); 5. int main() 6. { 7. int a=10; 8. fun(a); // error, which f()? 9. return 0; 10. } 11. void fun(int x) 12. { 13. std::cout << "Value of x is : " <<x<< std::endl; 14. } 15. void fun(int &b) 16. { 17. std::cout << "Value of b is : " <<b<< std::endl; 18. } The above example shows an error "call of overloaded 'fun(int&)' is ambiguous". The first function takes one integer argument and the second function takes a reference parameter as an argument. In this case, the compiler does not know which function is needed by the user as there is no syntactical difference between the fun(int) and fun(int &). C++ Operators Overloading Operator overloading is a compile-time polymorphism in which the operator is overloaded to provide the special meaning to the user-defined data type. Operator overloading is used to overload or redefines most of the operators available in C++. It is used to perform the operation on the user-defined data type. For example, C++ provides the ability to add the variables of the user-defined data type that is applied to the built-in data types. The advantage of Operators overloading is to perform different operations on the same operand. Operator that cannot be overloaded are as follows: Scope operator (::) Sizeof member selector(.) member pointer selector(*) ternary operator(?:) Syntax of Operator Overloading 1. return_type class_name : : operator op(argument_list) 2. { 3. // body of the function. 4. } Where the return type is the type of value returned by the function. class_name is the name of the class. operator op is an operator function where op is the operator being overloaded, and the operator is the keyword. Rules for Operator Overloading Existing operators can only be overloaded, but the new operators cannot be overloaded. The overloaded operator contains atleast one operand of the user-defined data type. We cannot use friend function to overload certain operators. However, the member function can be used to overload those operators. When unary operators are overloaded through a member function take no explicit arguments, but, if they are overloaded by a friend function, takes one argument. When binary operators are overloaded through a member function takes one explicit argument, and if they are overloaded through a friend function takes two explicit arguments. C++ Operators Overloading Example Let's see the simple example of operator overloading in C++. In this example, void operator ++ () operator function is defined (inside Test class). // program to overload the unary operator ++. 1. #include <iostream> 2. using namespace std; 3. class Test 4. { 5. private: 6. int num; 7. public: 8. Test(): num(8){} 9. void operator ++() { 10. num = num+2; 11. } 12. void Print() { 13. cout<<"The Count is: "<<num; 14. } 15. }; 16. int main() 17. { 1. class Student 2. { 3. public: 4. int id; //field or data member 5. float salary; //field or data member 6. String name;//field or data member 7. } C++ Object and Class Example Let's see an example of class that has two fields: id and name. It creates instance of the class, initializes the object and prints the object value. 1. #include <iostream> 2. using namespace std; 3. class Student { 4. public: 5. int id;//data member (also instance variable) 6. string name;//data member(also instance variable) 7. }; 8. int main() { 9. Student s1; //creating an object of Student 10. s1.id = 201; 11. s1.name = "Sonoo Jaiswal"; 12. cout<<s1.id<<endl; 13. cout<<s1.name<<endl; 14. return 0; 15. } Output: 201 Sonoo Jaiswal C++ Class Example: Initialize and Display data through method Let's see another example of C++ class where we are initializing and displaying object through method. 1. #include <iostream> 2. using namespace std; 3. class Student { 4. public: 5. int id;//data member (also instance variable) 6. string name;//data member(also instance variable) 7. void insert(int i, string n) 8. { 9. id = i; 10. name = n; 11. } 12. void display() 13. { 14. cout<<id<<" "<<name<<endl; 15. } 16. }; 17. int main(void) { 18. Student s1; //creating an object of Student 19. Student s2; //creating an object of Student 20. s1.insert(201, "Sonoo"); 21. s2.insert(202, "Nakul"); 22. s1.display(); 23. s2.display(); 24. return 0; 25. } Output: 201 Sonoo 202 Nakul C++ Class Example: Store and Display Employee Information Let's see another example of C++ class where we are storing and displaying employee information using method. 1. #include <iostream> 2. using namespace std; 3. class Employee { 4. public: 5. int id;//data member (also instance variable) 6. string name;//data member(also instance variable) 7. float salary; 8. void insert(int i, string n, float s) 9. { 10. id = i; 11. name = n; 12. salary = s; 13. } 14. void display() 15. { 16. cout<<id<<" "<<name<<" "<<salary<<endl; 17. } 18. }; 19. int main(void) { 20. Employee e1; //creating an object of Employee 21. Employee e2; //creating an object of Employee 22. e1.insert(201, "Sonoo",990000); 23. e2.insert(202, "Nakul", 29000); 24. e1.display(); 25. e2.display(); 26. return 0; 27. } Output: 201 Sonoo 990000 202 Nakul 29000 C++ Constructor In C++, constructor is a special method which is invoked automatically at the time of object creation. It is used to initialize the data members of new object generally. The constructor in C++ has the same name as class or structure. In brief, A particular procedure called a constructor is called automatically when an object is created in C++. In general, it is employed to create the data members of new things. In C++, the class or structure name also serves as the constructor name. When an object is completed, the constructor is called. Because it creates the values or gives data for the thing, it is known as a constructor. The Constructors prototype looks like this: 1. <class-name> (list-of-parameters); The following syntax is used to define the class's constructor: 1. <class-name> (list-of-parameters) { // constructor definition } The following syntax is used to define a constructor outside of a class: 1. <class-name>: :<class-name> (list-of-parameters){ // constructor definition} Constructors lack a return type since they don't have a return value. There can be two types of constructors in C++. Default constructor Parameterized constructor C++ Default Constructor A constructor which has no argument is known as default constructor. It is invoked at the time of creating object. Let's see the simple example of C++ default Constructor. A member function known as a copy constructor initializes an item using another object from the same class-an in-depth discussion on Copy Constructors. Every time we specify one or more non-default constructors (with parameters) for a class, we also need to include a default constructor (without parameters), as the compiler won't supply one in this circumstance. The best practice is to always declare a default constructor, even though it is not required. A reference to an object belonging to the same class is required by the copy constructor. 1. Sample(Sample &t) 2. { 3. id=t.id; 4. } What is a destructor in C++? An equivalent special member function to a constructor is a destructor. The constructor creates class objects, which are destroyed by the destructor. The word "destructor," followed by the tilde () symbol, is the same as the class name. You can only define one destructor at a time. One method of destroying an object made by a constructor is to use a destructor. Destructors cannot be overloaded as a result. Destructors don't take any arguments and don't give anything back. As soon as the item leaves the scope, it is immediately called. Destructors free up the memory used by the objects the constructor generated. Destructor reverses the process of creating things by destroying them. The language used to define the class's destructor 1. ~ <class-name>() 2. { 3. } The language used to define the class's destructor outside of it 1. <class-name>: : ~ <class-name>(){} C++ Destructor A destructor works opposite to constructor; it destructs the objects of classes. It can be defined only once in a class. Like constructors, it is invoked automatically. A destructor is defined like constructor. It must have same name as class. But it is prefixed with a tilde sign (~). Note: C++ destructor cannot have parameters. Moreover, modifiers can't be applied on destructors. C++ Constructor and Destructor Example Let's see an example of constructor and destructor in C++ which is called automatically. 1. #include <iostream> 2. using namespace std; 3. class Employee 4. { 5. public: 6. Employee() 7. { 8. cout<<"Constructor Invoked"<<endl; 9. } 10. ~Employee() 11. { 12. cout<<"Destructor Invoked"<<endl; 13. } 14. }; 15. int main(void) 16. { 17. Employee e1; //creating an object of Employee 18. Employee e2; //creating an object of Employee 19. return 0; 20. } Output: Constructor Invoked Constructor Invoked Destructor Invoked Destructor Invoked UNIT-4 Pointer, Polymorphism & Inheritance Pointer (Pointer to Object, this Pointer, Pointer to Derive Class), Introduction to Polymorphism (Runtime Polymorphism, Compiletime Polymorphism), Operator Overloading, Virtual Function, Inheritance (Single Inheritance, Multiple Inheritance, Multilevel Inheritance, Hierarchical Inheritance, Hybrid Inheritance), Virtual Base Class, Abstract Class. C++ Pointers The pointer in C++ language is a variable, it is also known as locator or indicator that points to an address of a value. The symbol of an address is represented by a pointer. In addition to creating and modifying dynamic data structures, they allow programs to emulate call-by-reference. One of the principal applications of pointers is iterating through the components of arrays or other data structures. The pointer variable that refers to the same data type as the variable you're dealing with has the address of that variable set to it (such as an int or string). Syntax 1. datatype *var_name; 2. int *ptr; // ptr can point to an address which holds int data How to use a pointer? 1. Establish a pointer variable. 2. employing the unary operator (&), which yields the address of the variable, to assign a pointer to a variable's address. 3. Using the unary operator (*), which gives the variable's value at the address provided by its argument, one can access the value stored in an address. Since the data type knows how many bytes the information is held in, we associate it with a reference. The size of the data type to which a pointer points is added when we increment a pointer. Advantage of pointer 1) Pointer reduces the code and improves the performance, it is used to retrieving strings, trees etc. and used with arrays, structures and functions. 2) We can return multiple values from function using pointer. 3) It makes you able to access any memory location in the computer's memory. Usage of pointer There are many usage of pointers in C++ language. 1. int *ptr1 = 0; 2. int *ptr2 = NULL; What is a pointer to a pointer? In C++, we have the ability to build a pointer to another pointer, which might then point to data or another pointer. The unary operator (*) is all that is needed in the syntax for declaring the pointer for each level of indirection. 1. char a; 2. char *b; 3. char ** c; 4. a = 'g'; 5. b = &a; 6. c = &b; Here b points to a char that stores 'g', and c points to the pointer b. What are references and pointers? 1. Call-By-Value 2. Call-By-Reference with a Pointer Argument 3. Call-By-Reference with a Reference Argument 1. #include 2. using namespace std; 3. // Pass-by-Value 4. int square1(int n) 5. {cout << "address of n1 in square1(): " << &n << "\n"; 6. n *= n; 7. return n; 8. } 9. // Pass-by-Reference with Pointer Arguments 10. void square2(int* n) 11. { 12. cout << "address of n2 in square2(): " << n << "\n"; 13. *n *= *n; 14. } 15. // Pass-by-Reference with Reference Arguments 16. void square3(int& n) 17. { 18. 19. cout << "address of n3 in square3(): " << &n << "\n"; 20. n *= n; 21. } 22. void example() 23. { 24. // Call-by-Value 25. int n1 = 8; 26. cout << "address of n1 in main(): " << &n1 << "\n"; 27. cout << "Square of n1: " << square1(n1) << "\n"; 28. cout << "No change in n1: " << n1 << "\n"; 29. 30. // Call-by-Reference with Pointer Arguments 31. int n2 = 8; 32. cout << "address of n2 in main(): " << &n2 << "\n"; 33. square2(&n2); 34. cout << "Square of n2: " << n2 << "\n"; 35. cout << "Change reflected in n2: " << n2 << "\n"; 36. 37. // Call-by-Reference with Reference Arguments 38. int n3 = 8; 39. cout << "address of n3 in main(): " << &n3 << "\n"; 40. square3(n3); 41. cout << "Square of n3: " << n3 << "\n"; 42. cout << "Change reflected in n3: " << n3 << "\n"; 43. } 44. // Driver program 45. int main() { example(); } Output C++ Polymorphism The term "Polymorphism" is the combination of "poly" + "morphs" which means many forms. It is a greek word. In object-oriented programming, we use 3 main concepts: inheritance, encapsulation, and polymorphism. Real Life Example Of Polymorphism Let's consider a real-life example of polymorphism. A lady behaves like a teacher in a classroom, mother or daughter in a home and customer in a market. Here, a single person is behaving differently according to the situations. There are two types of polymorphism in C++: Compile time polymorphism: The overloaded functions are invoked by matching the type and number of arguments. This information is available at the compile time and, therefore, compiler selects the appropriate function at the compile time. It is achieved by function overloading and operator overloading which is also known as static binding or early binding. Now, let's consider the case where function name and prototype is same. 1. class A // base class declaration. 2. { 3. int a; 4. public: 5. void display() 6. { 7. cout<< "Class A "; 8. } 9. }; 10. class B : public A // derived class declaration. 11. { 12. int b; 28. Shape sh; // base class object. 29. Rectangle rec; 30. Circle cir; 31. s=&sh; 32. s->draw(); 33. s=&rec; 34. s->draw(); 35. s=? 36. s->draw(); 37. } Output: drawing... drawing rectangle... drawing circle... Runtime Polymorphism with Data Members Runtime Polymorphism can be achieved by data members in C++. Let's see an example where we are accessing the field by reference variable which refers to the instance of derived class. 1. #include <iostream> 2. using namespace std; 3. class Animal { // base class declaration. 4. public: 5. string color = "Black"; 6. }; 7. class Dog: public Animal // inheriting Animal class. 8. { 9. public: 10. string color = "Grey"; 11. }; 12. int main(void) { 13. Animal d= Dog(); 14. cout<<d.color; 15. } Output: Black C++ Inheritance In C++, inheritance is a process in which one object acquires all the properties and behaviors of its parent object automatically. In such way, you can reuse, extend or modify the attributes and behaviors which are defined in other class. In C++, the class which inherits the members of another class is called derived class and the class whose members are inherited is called base class. The derived class is the specialized class for the base class. Advantage of C++ Inheritance Code reusability: Now you can reuse the members of your parent class. So, there is no need to define the member again. So less code is required in the class. Types Of Inheritance C++ supports five types of inheritance: Single inheritance Multiple inheritance Hierarchical inheritance Multilevel inheritance Hybrid inheritance Derived Classes A Derived class is defined as the class derived from the base class. The Syntax of Derived class: 1. class derived_class_name :: visibility-mode base_class_name 2. { 3. // body of the derived class. 4. } Where, derived_class_name: It is the name of the derived class. visibility mode: The visibility mode specifies whether the features of the base class are publicly inherited or privately inherited. It can be public or private. base_class_name: It is the name of the base class. When the base class is privately inherited by the derived class, public members of the base class becomes the private members of the derived class. Therefore, the public members of the base class are not accessible by the objects of the derived class only by the member functions of the derived class. When the base class is publicly inherited by the derived class, public members of the base class also become the public members of the derived class. Therefore, the public members of the base class are accessible by the objects of the derived class as well as by the member functions of the base class. Note: In C++, the default mode of visibility is private. The private members of the base class are never inherited. C++ Single Inheritance Single inheritance is defined as the inheritance in which a derived class is inherited from the only one base class. Where 'A' is the base class, and 'B' is the derived class. ADVERTISEMENT How to make a Private Member Inheritable The private member is not inheritable. If we modify the visibility mode by making it public, but this takes away the advantage of data hiding. C++ introduces a third visibility modifier, i.e., protected. The member which is declared as protected will be accessible to all the member functions within the class as well as the class immediately derived from it. Visibility modes can be classified into three categories: Public: When the member is declared as public, it is accessible to all the functions of the program. Private: When the member is declared as private, it is accessible within the class only. Protected: When the member is declared as protected, it is accessible within its own class as well as the class immediately derived from it. ADVERTISEMENT Visibility of Inherited Members Base class visibility Derived class visibility Public Private Protected Private Not Inherited Not Inherited Not Inherited Protected Protected Private Protected Public Public Private Protected C++ Multilevel Inheritance Multilevel inheritance is a process of deriving a class from another derived class. C++ Multi Level Inheritance Example When one class inherits another class which is further inherited by another class, it is known as multi level inheritance in C++. Inheritance is transitive so the last derived class acquires all the members of all its base classes. Let's see the example of multi level inheritance in C++. 1. #include <iostream> 2. using namespace std; 3. class Animal { 4. public: 5. void eat() { 6. cout<<"Eating..."<<endl; 7. } 8. }; 9. class Dog: public Animal 10. { 11. public: 12. void bark(){ 13. cout<<"Barking..."<<endl; 14. } 15. }; 16. class BabyDog: public Dog 17. { 18. public: 19. void weep() { 20. cout<<"Weeping..."; 21. } 22. }; 23. int main(void) { 24. BabyDog d1; 25. d1.eat(); 26. d1.bark(); 27. d1.weep(); 28. return 0; 29. } Output: Eating... Barking... Weeping... C++ Multiple Inheritance Multiple inheritance is the process of deriving a new class that inherits the attributes from two or more classes. 1. class D : visibility B-1, visibility B-2, ? 2. { 3. // Body of the class; 4. } Let's see a simple example of multiple inheritance. 1. #include <iostream> 2. using namespace std; 3. class A 4. { 5. protected: 6. int a; 7. public: 8. void get_a(int n) 9. { 10. a = n; 11. } 12. }; 13. 14. class B 15. { 16. protected: 17. int b; 18. public: 19. void get_b(int n) 20. { 12. void display() 13. { 14. cout<<?Class B?; 15. } 16. } ; In the above case, the function of the derived class overrides the method of the base class. Therefore, call to the display() function will simply call the function defined in the derived class. If we want to invoke the base class function, we can use the class resolution operator. 1. int main() 2. { 3. B b; 4. b.display(); // Calling the display() function of B class. 5. b.B :: display(); // Calling the display() function defined in B class. 6. } C++ Hybrid Inheritance Hybrid inheritance is a combination of more than one type of inheritance. Let's see a simple example: 1. #include <iostream> 2. using namespace std; 3. class A 4. { 5. protected: 6. int a; 7. public: 8. void get_a() 9. { 10. std::cout << "Enter the value of 'a' : " << std::endl; 11. cin>>a; 12. } 13. }; 14. 15. class B : public A 16. { 17. protected: 18. int b; 19. public: 20. void get_b() 21. { 22. std::cout << "Enter the value of 'b' : " << std::endl; 23. cin>>b; 24. } 25. }; 26. class C 27. { 28. protected: 29. int c; 30. public: 31. void get_c() 32. { 33. std::cout << "Enter the value of c is : " << std::endl; 34. cin>>c; 35. } 36. }; 37. 38. class D : public B, public C 39. { 40. protected: 41. int d; 42. public: 43. void mul() 44. { 45. get_a(); 46. get_b(); 47. get_c(); 48. std::cout << "Multiplication of a,b,c is : " <<a*b*c<< std::endl; 49. } 50. }; 51. int main() 52. { 53. D d; 54. d.mul(); 55. return 0; 56. } Output: Enter the value of 'a' : 10 Enter the value of 'b' : 20 Enter the value of c is : 30 Multiplication of a,b,c is : 6000 C++ Hierarchical Inheritance Hierarchical inheritance is defined as the process of deriving more than one class from a base class. Syntax of Hierarchical inheritance: 1. class A 2. { 3. // body of the class A. 4. } 5. class B : public A 6. { 7. // body of class B. 8. } 9. class C : public A 10. { 11. // body of class C. 12. } 13. class D : public A 14. { 15. // body of class D. 16. } Let's see a simple example: 1. #include <iostream> 2. using namespace std; 3. class Shape // Declaration of base class. 4. { 5. public: 6. int a; 7. int b; 8. void get_data(int n,int m) 9. { 10. a= n; 11. b = m; Once we're done working with a file, we need to close it using the close() function. my_file.close(); Let's take an example program to look at these operations. Example 1: Opening and Closing a File #include <iostream> #include <fstream> using namespace std; int main() { // opening a text file for writing ofstream my_file("example.txt"); // close the file my_file.close(); return 0; } This code will open and close the file example.txt. Note: If there's no such file to open, ofstream my_file("example.txt"); will instead create a new file named example.txt. Check the File for Errors In file handling, it's important to ensure the file was opened without any error before we can perform any further operations on it.There are three common ways to check files for errors: 1. By Checking the File Object ofstream my_file("example.txt"); // check if the file has been opened properly if (!my_file) { // print error message cout << "Error opening the file." << endl; // terminate the main() function return 1; } Notice the condition in the if statement: if (!my_file) {...} This method checks if the file is in an error state by evaluating the file object itself. If the file has been opened successfully, the condition evaluates to true. If there's an error, it evaluates to false, and you can handle the error accordingly. 2. Using the is_open() Function The is_open() function returns true - if the file was opened successfully. false - if the file failed to open or if it is in a state of error. For example, ofstream my_file("example.txt"); if (!my_file.is_open()) { cout << "Error opening the file." << endl; return 1; } 3. Using the fail() Function The fail() function returns true - if the file failed to open or if it is in a state of error. false - if the file was opened successfully. ofstream my_file("example.txt"); if (my_file.fail()) { cout << "Error opening the file." << endl; return 1; } Note: For simplicity, we recommend using the first method. Read From a File Reading from text files is done by opening the file using the ifstream class. For example, ifstream my_file("example.txt"); Then, we need to read the file line-by-line. To do this, we need to loop through each line of the file until all the lines are read, i.e., until we reach the end of the file. We use the eof() function for this purpose, which returns true - if the file pointer points to the end of the file false - if the file pointer doesn't point to the end of the file For example, // variable to store file content string line; // loop until the end of the file while (!my_file.eof()) { // store the current line of the file // in the "line" variable getline(my_file, line); // print the line variable cout << line << endl; } Here, the while loop will run until the end of the file. In each iteration of the loop, getline(my_file, line); reads the current line of the file and stores it in the line variable. Then, it prints the line variable. Next, let's clarify this with a working example. Example 2: Read From a File #include <iostream> #include <fstream> using namespace std; int main() { // open a text file for reading ifstream my_file("example.txt"); // check the file for errors if(!my_file) { cout << "Error: Unable to open the file." << endl; return 1; } // store the contents of the file in "line" string string line; // loop until the end of the text file while (!my_file.eof()) { // store the current line of the file // in the "line" variable getline(my_file, line); // print the line variable cout << line << endl; } // append multiple lines to the file my_file << "Line 4" << endl; my_file << "Line 5" << endl; my_file << "Line 6" << endl; // close the file my_file.close(); return 0; } This will add the following lines to example.txt: Line 4 Line 5 Line 6 File Handling With fstream Instead of using ifstream to read from a file and ofstream to write to the file, we can simply use the fstream class for all file operations. The constructor for fstream allows you to specify the file name and the mode for file operations. Mode Description ios::in Opens the file to read (default for ifstream). ios::out Opens the file to write (default for ofstream). ios::app Opens the file and appends new content to itat the end. Let's look at an example: #include <iostream> #include <fstream> using namespace std; int main() { // 1. write to a text file fstream my_file("example.txt", ios::out); if (my_file) { my_file << "This is a test line." << endl; my_file.close(); } else { cout << "Unable to open file for writing." << endl; return 1; } // 2. read from the same file string line; my_file.open("example.txt", ios::in); if (my_file) { while (!my_file.eof()) { getline(my_file, line); cout << "Read from file: " << line << endl; } my_file.close(); } else { cout << "Unable to open file for reading." << endl; return 1; } // 3. append data to the end of the file my_file.open("example.txt", ios::app); if (my_file) { my_file << "This is another test line, appended to the file." << endl; my_file.close(); } else { cout << "Unable to open file for appending." << endl; return 1; } return 0; } Output Read from file: This is a test line. Read from file: If we look at the file after running the program, we will find the following contents: C++ Exception Handling Exception Handling in C++ is a process to handle runtime errors. We perform exception handling so the normal flow of the application can be maintained even after runtime errors. In C++, exception is an event or object which is thrown at runtime. All exceptions are derived from std::exception class. It is a runtime error which can be handled. If we don't handle the exception, it prints exception message and terminates the program. Advantage It maintains the normal flow of the application. In such case, rest of the code is executed even after exception. C++ Exception Classes In C++ standard exceptions are defined in <exception> class that we can use inside our programs. The arrangement of parent-child class hierarchy is shown below: