Hi everyone and welcome to Aapna College. In today's one shot, we will cover all the OOPs from zero to advance from interview point of view. Whether it is your placement interview, whether it is our internship interview or we are preparing for OOPs exam in college exams. This one shot is going to be sufficient for all the things. But we have specifically prepared this for placement and internship interviews.
So OOPs means Object Oriented Programming is a very important concept. So let's get started. which majority companies ask in their tech interviews. So, it is very important to have a strong understanding of OOPS so that our interviews go very well. Along with that, our understanding of programming is also very big.
Because in companies, we have to implement OOPS many times in many places. So, the stronger the concept is from the beginning, the more we will benefit later. So, in today's one shot, we will cover theory concepts, we will cover many examples.
We will cover many important definitions which we have to remember because they are asked in interviews. And along with this, we will also be writing the code of every single concept. So we will be getting practical examples of everything that we are reading, which is seen in the code in C++. And along with this, at the end of this whole one shot, we will be getting 30 MCQ questions.
Due to which, whatever understanding we have taken during the whole lecture, it will be getting stronger. So let's start our OOPS journey. Hi everyone, and now we are going to start our object-oriented programming journey. Now when we talk about object-oriented programming, in this lecture, we will basically talk about our objects, what exactly objects are in C++, and what are the different concepts related to objects in C++. This chapter is important because in interviews, whenever there are interviews for internship placement, there are interviews for SD position, software engineering position.
So there are many related questions related to this. So that's why in this chapter, definitions become very important. Because directly interviewer can ask us any complex term definition. Along with that, all the examples that we discuss become important. Because interviewer can ask us examples too.
So we will understand the meaning of things. Along with that, we will talk about definition and examples in detail. So whenever we say object oriented programming, what exactly does it mean? Object Oriented Programming is basically a better way to write code.
It is not that object oriented programming is always compulsory to use. But generally, there are many real life scenarios in which if you use the concepts of OOPS in code, then our code becomes much better, especially at the organization level, that is, when we work inside companies. Generally, whenever we write C++ code, we can implement all the logic of OOPS in C++ without OOPS. But when we use OOPS to implement the same logic, there are many real-life scenarios which are easy to represent in code, for which C++ code is written very easily. And this line is very important because we will learn the meaning of this in the whole lecture.
That how we convert real-life scenarios into C++ code using OOPS concept. Now if we talk about practical implementation of OOPS, then in C++, if we have heard about vector library, or string library or stack library all these libraries exist in C++ STL because of OOPs because to implement all these OOPs concepts are used internally so we are going to create many classes and learn many OOPs concepts in this chapter before learning OOPs concepts there are two important terms which we should know one is our class and one is our object What is an object? In the real world, any entity, entity means if we pick up anything, then we can call it an object.
This pen is an object, my laptop is an object, or our phone is an object. So all the entities of our real world, we call anything an object. And when we want to convert these entities into C++ code, then we make them objects in the C++ code as well. And what is class? Class is basically like a blueprint of these objects.
The work of a blueprint is to tell how the object will look. Let's take a very basic example for this. For example, what did Toyota do?
They set up a factory. So, Toyota internally made a blueprint inside their factory that how all their vehicles should look. So Toyota looks at this blueprint and makes its car 1, then again looks at the blueprint and makes its car 2, then again looks at the blueprint and makes its car 3. So in this way Toyota can make unlimited cars.
So in this case, these cars, car 1, car 2, car 3, these are all objects. These are different entities. Every entity is different in itself.
This is also different, this is also different. And their blueprint, which I was telling you about, How should this object look like? How should this object look like?
We call this blueprint class. So class can also be a blueprint for objects. It can also be a group of objects.
We can also imagine it as a group of objects. Like in our school, in our college, we all students sit in the same class. So what happened to that class?
That class became a group of our students. And in that case, we students become objects in our real world scenario. Now let's take another practical example to understand it in more detail. For example, In our college, there must be a system in which every teacher has an account.
All the teachers who work in the college, their information must be stored in the college system. So we are also told to design a system using C++ for our college, which can store all the information of the teachers. So first of all, we will see logically, what information should be stored with the teacher.
For one, we can store the name of each teacher. Along with that, we can store the department of each teacher. We can store the subject of each teacher. We can store the salary of each teacher.
So what happened to all these things? So all these things happened. Some properties, we call them properties in technical language.
Properties means some values which are associated with this entity. What is a teacher? For our code, a teacher will become an entity. The entity which has some properties in itself, that if we want to store the information of the teacher in the code, then along with that we have to store this extra info also. And along with that, there will be some extra functions of the teachers.
Like what all functions will be there? It is possible that we have a function for a teacher, change the teacher's department. That if the teacher shifts from mechanical department to civil department, then change department is a function which should be associated with the teacher. so that anyone can change the teacher's department in the system.
Along with that, there can be salary tax calculation, or there can be different functions associated with the teacher. But we took one basic function. So what is a teacher?
Because teacher is a real world entity, we will make the teacher our object. And with every object, our different properties are associated. And there are some functions associated with this, which we call our method in technical language. Method is nothing but a function which is written inside a class.
The functions which we make for a class or objects, we call them our method. Normally, if we want to store information of one teacher in C++ code, then what we do is, we make a string for it. If we want to store the name of a teacher, then this string is named t1.
After that we make another string that we have to store their department for our teacher t1. And similarly if another teacher comes then we have to write again string t2 name and department. So in this way if there are 50 teachers in our system then we have to write code repeatedly for them if we are making only variables.
So in such a case code cannot be reused. If we write logic once. So why should we rewrite that logic? This is bad programming.
So to avoid this bad programming, we use the concept of oops. That once a class is made, once a blueprint is made, that means once the factory tells the blueprint, then what will Toyota do? The car will manufacture in the same format one after the other.
So likewise, we have to tell in our C++ code once that what properties and what methods will the teacher have? And then we can create profiles of many different teachers for ourselves. So... So instead of creating a lot of variables in our C++ code, what does the concept of Poops or classes and objects say? This concept tells us to make a class.
Class means you write a blueprint of how a teacher should look. After that, you make class object 1, meaning teacher 1. Make class object 2, meaning teacher 2. We will create class object 3, teacher 3. So now you want 50 teachers, you want 100 teachers, you want 1 lakh teachers, now you will not have to repeat the code again and again. The reusability will come in the code because we can use the same class, the same blueprint to create all the objects. Now the concept of objects and classes does not only exist in C++, it also exists in languages like Java.
Or if we are doing Python, JavaScript or any other language, then there also generally this concept exists. And if you work in a company, then oops is used a lot in our day to day programming. Now whenever we talk about oops, let's take another practical example.
For example, there is Amazon. Amazon has made its website. Every product list on Amazon's website has some common things in it.
Every product has its own name, price, description. Every product may have a discount amount. Like 5% discount, 10% discount, 0% discount.
So this is Amazon's product 1. Similarly, we can make another product. This is Amazon's product 2. which includes name, price, description, discount, all four things. This is Amazon's product tree, which includes name, price, description, discount, all four things. So, the different products of Amazon, internally, Amazon could have implemented them as objects. Meaning, the logic of classes and objects would have been used there.
So, wherever we have to create such entities in the code, which are a little close to the real world, in which we have to create many properties and methods. We will use classes and objects there. To use classes and objects, we have to declare a class.
To declare a class, we write our class keyword and then write the name of our class. Generally, whatever class we want to create for our entity, for example, we want to create a class to create teachers, to create a teacher system, then we will keep the name of our class as teacher. And this way we create our class.
So, there is a general syntax to write our class in the code. In this, we write our properties. And in this, we are writing our methods.
So, once we create a teacher class. We have created this oops.cpp file. In this, we have included the iostream header file.
Along with that, we have included the string because we are going to declare the string type data. So, this is basically our boilerplate code. Now, in this code, we will create a class. So, our class is our keyword. The name of the class is going to be teacher.
In this way, we will put curly braces and always a semicolon is put at the end of the class. So, it is known that our class is ending here. Now, in this class, we first tell all the properties that should be in the class.
Then, we tell all the methods that should be in the class. Means, when we make an object of teacher, then what qualities and values should be there near the object? One should be the name of the teacher. Name of string type should be of string type.
So, teacher should have a string name. Teacher should have a string department. Teacher should have a string subject.
Along with that, teacher should have some salary. So, we can write our salary by floating. Or we can make it double instead of float. So, this is our salary. So, what happened?
Some of our properties related to teacher happened. These properties are called as properties in technical language. Or we also call them attributes. So wherever you hear the word attribute, wherever you hear the word property, it means that we are talking about all these values.
Apart from that, we also have some methods related to teachers. Let us minimize this. What methods can be related to teachers? We have discussed one method. Method means you just have to write the function.
We are just writing that function inside this class. So here we can make void changeDepartment. What does changeDepartment function do? It takes a string. We can call it newDepartment.
It takes a string named newDepartment. And the old department value, in this department value, it assigns this newDepartment value. So we have written our method. Apart from this, we can write different methods here. Methods are also called member functions in C++.
Member functions are called because these functions become members of our class. So, that's why they are also called member functions. So, wherever we hear member functions, wherever we hear methods, we are talking about class functions. So, in this way, we have created our class. Now, how to create an object?
To create an object, what can we do in the main function? First, we will write the name of our class, then we will write the name of our object. We can also write object as obj1 or if it is a teacher, then we can call it t1. So this is our teacher T1 object.
Means we have created an object for our first teacher. In the same way, we can create any number of objects for teachers. We can create objects, this is our T3 object, this is our T4 object.
And now every individual object has its name, department, subject, salary, all the information. Now what we have to do is update that information. Now let's take an example of only this teacher T1. Now if we want to assign value to T1, that is if we want to access its properties for any object, then we use dot operator.
Dot operator means, for example, we created an object teacherT1. Now we know internally T1 has different properties. T1 has a name, a department and other information.
Now if we want to access the name of T1, we simply write t1.name. Now we can treat this as a single variable. If we want to assign a value to it, we will write equal to value.
If we want to print its value, we can simply cout t1.name. This means that we can use the same method to create a new variable. we are trying to access the name property of t1 object. Similarly, if we want to access the function or method, then we can access our method in this way. So let us try to assign a name to the teacher.
Let's suppose I wrote my name in t1.name. And in t1.subject, we write the subject in the same way, c++. And in t1.department, we write, let's suppose, computer science.
And in t1.salary, I have written, Let's suppose, salary is 25000. Now, what happened is, these are my basic values which I have assigned. But, if we run this code now, by the way, nothing should be printed now. Let's see out the value of t1.name here.
Now if we try to run this code simply, this is the command that I am writing for running the code because my file name is oops.cpp so I am writing oops.cpp here I am invoking g++ compiler I have used this flag because I am using c++11 but you can remove it from your terminal command it will not make any difference and this is the executable file which will be generated for me So when I will run this, I will get an error here and what is the error? Error caret department is a private member of teacher, salary is a private member of teacher, name is a private member of teacher, implicitly declared private here. So why are these private member private member things showing me this way?
Actually whenever we study classes and objects, then it is not enough to define only properties and member function. Along with them we have to define one more additional thing, which we call access modifiers in coding. Access modifier is a special keyword. Keyword means a special reserved word. We have three access modifiers in C++.
One is private, one is public, and one is protected. All the data of the class, data means properties or attributes, all the data and methods of the class, we want them to be accessible only inside the class. Means all the attributes and methods we have created in the class, which we don't want to send outside the class we want to keep access to it only inside the class we make all of them private and by default by default inside C++ everything is private inside C++ your attributes are also private inside C++ your member functions are also private that's why we got an error that the name outside the class means inside the main function the name we are accessing and changing its value or we are printing the name, all these things are not possible because what happened in C++? This class has a private attribute, we cannot access it outside the class, so that error was coming because of access modifier.
So if in any class explicitly if we want to show anything private, then what can we do for that? For that we can write our private keyword. Here as soon as we wrote private and colon, it got highlighted. So, writing private colon means that all the things written after this will automatically become private. By default, it is also private, but we can write it in this way and tell.
We have another access modifier whose name is public. Whatever we declare public, data and methods, all of them will be accessible to everyone. That means we can access them inside the class and we can access them outside the class.
For example, if I write public instead of private here, So that means this whole data and these values, this whole function will be accessible outside the class. So this is the class, now we can access this in the main function and now there will be no error in our code. Let us minimize this a bit and rerun our code.
So as soon as we rerun the code this time, our teacher's name will be printed for us. So in this way, we can print any value we want. And there is a third access modifier which we call protect.
Protected means when we do inheritance concept then we will do it in more detail because now its concept will not be clear to you. But protected means whatever data and method we want to make accessible in the class and one in our derived class. Basically when inheritance is there then one class sends its properties to another class. So private properties cannot go to the other class.
So, the private property we want to send in this small class, we make all those properties protected or we make those methods protected. But this concept of protected, we will do it in detail while doing inheritance, so it will be clear to you there. For now, we have to focus on private and public.
Private is the one which can be accessed by the class inside the class. Means this function can access the private. Here the department was private, so there will be no error here. But the public will not be scared.
Our main function can also be accessed or any other class can be accessed to the public. If we want, we made one class for the teacher here. We can also make a class of our student.
So, there can be different properties of the student. So, we can define our properties of the student in this way. That the student has a student's name. One could be the integer role number of the student. One could be the integer age of the student.
So, in this way, multiple properties of our student class can also be there. Which is near the object of the student class. Now, let's suppose we have created our class in this way, teacher class. Generally, in the system of colleges, name, department, subject are things that we can give access to everyone.
But the salary access is generally given to the accounts team. So what we can do is, we can make this salary a private member instead of public. So we will cut it from here and what we will do is, we can declare our private flag, private access modifier. And here we will declare our salary. So now this is our teacher class in which this member is private.
And all these members are public. Now when we access the salary, there will be an error. Because salary has become private.
So here, salary is a private member of teacher. So we will not be able to access this value here. But we can access all the other values.
So in this way, depending on the situation, which object we are implementing, which data should be accessed outside the class, which data should not be logically accessed outside the class. We make some data members private and some protected. Generally, if we have to give access to our protected data, to the main function or to any other class, then we don't give access directly.
For example, if I still have to set or print my teacher's salary in the main, then we can make some special functions for that. And we can keep those functions public. For example, I have made a function void set. salary, set salary means set the value of salary so here we will take int value of salary s and our salary, here which is the salary variable? this one is the salary variable This will be a double value.
So, we will assign this S value to the salary. So, what happened with that? With this function, we will be able to set the salary value.
And let's make one more function, double. Get salary. What will the get salary function do?
It will return our salary value. Now here we can get the question that now we have got access even though we made salary private but still we got access to salary from these functions. So this access still goes on in many cases.
And these special functions, this function has a technical name, we call it setter and this function is called getter function. Setter function works to set private values and generally we use getter function to get value of private values. We are not able to directly access salary.
But yes, indirectly through these public functions we will be able to access. Now if we want we can set the value of our salary again. So in t1.setSalary we will pass our value again to 25,000. And here this time we can see out t1.getSalary. So we will get the value also returned.
So in this way our entire... Information is there, we can print it if we want. Now next we are going to talk about another important term in OOPS which we call encapsulation. OOPS is a subject, you will find it very easy.
As compared to C++, DSA, OOPS is a very easy concept. It has theory only, nothing difficult to understand. But OOPS has a small thing which is the names of things. Meaning is very easy, they have kept the names of encapsulation difficult.
This is the difference. OOPS has four major pillars. Four major pillars means, OOPS's one shot has four major topics, which are asked in interviews. First of all, tell us about encapsulation.
Tell us about encapsulation, tell us about encapsulation's definition. Second is abstraction. Third is inheritance.
And fourth is polymorphism. We call these four words the pillars of OOPS. And you should remember the definitions of these four by heart. Because it will be asked in your interviews.
Many times in the college exams of computer science students, OOPS is also mentioned. And their definition is very easy and we will do it through many examples. So now we are going to discuss the first pillar of these.
Which is called encapsulation. I always hear the word capsule in encapsulation whenever I listen to encapsulation. So it means the same. Basically encapsulation means that you took some data. Data means you took some properties.
And you took some member functions. We took member functions, normal functions, and what did you do with all of them? You made a capsule out of them.
Meaning, we made a capsule out of both of these things. So, this became encapsulation. And this capsule, we call it our class. So, encapsulation is nothing. We took some data, meaning some properties, and some methods, meaning some member functions, and we combined them and wrote them all in the class.
This is what encapsulation is. So we have already done encapsulation. The teacher class we made, in this teacher class, we wrote some properties, some data and some functions.
So what did we do? We implemented encapsulation. So making a class and declaring member functions and data members in it is encapsulation. So just remember its definition. Encapsulation is wrapping up of data and member functions in a single unit.
This capsule is a single unit which we call glass. So this is encapsulation. Now the concept of encapsulation helps us in data hiding.
What does data hiding mean? Data hiding means hiding important information, sensitive information. And how does encapsulation concept help in data hiding?
Basically for your sensitive information, it means a skill. private access modifier use use that sensitive information private so outside the class whatever sensitive information we have if it is not accessed outside then no one will know about it. For example we design a bank system in C++ so for them we can make a class.
Let's create a class called account now this account class will have a lot of different values a lot of different data will be there for example one will be our account ID Apart from that, we would have given a username to our user. So, the username of our account will come. Along with that, we can show our balance of floating or double.
How much balance is there in our account. Now, let's suppose for a bank system, this balance information is very sensitive. You show someone account ID, you show someone username, but you can't show balance. Or if there was one more string of password in it.
So the password of any user would also be very sensitive information. We don't want anyone to have access to it outside the class. The meaning of not having access outside the class is that because we are using things in a single file right now.
But whenever you go inside the company, whenever we work on a big banking system, there can be a lot of different C++ files. And a different new class is being created in every C++ file, something new is being created and it is importing data from another file. So we don't want our password or balance information to be there with other files.
So if we make these two data members private here, This is how it happened. We have basically implemented data hiding in our code. That our sensitive data, either make it private or make it protected.
So that data will be hidden from the other normal classes or functions. This data is still public, anyone can access it and see it. So, in this way we implement data hiding using encapsulation. Class is made, only then access modifiers can be used.
And access modifiers are used, only then data hiding can be done. So, these are the basic concepts that are asked in interviews. We will ask you what is encapsulation? Give an example of encapsulation.
What is data hiding? Give an example of data hiding. What are the access modifiers in C++? Write an example using the class for them. So, basic questions like this are asked.
So next we are going to talk about a special function called constructor. Whenever we talk about classes and objects, constructor is a very important concept. It is a very easy concept. Constructor is a special method.
Special method means it is a very special function which is automatically invoked. It automatically calls C++ whenever we create a new object. For example, let's go to our code.
We have made a teacher object in our code. Where have we made it? This is our teacher class.
Let us minimize this. This is our teacher class and for this teacher class we have made our teacher object here. As soon as we write the object creation line here, the constructor is being called automatically internally. We don't see that call going on but the compiler automatically calls the constructor whenever we create any new object. Now what is a constructor exactly?
Constructor is a special function which works for objects. initialize. It means that whenever we make a class, class is a blueprint that what member functions should be in our object, what data should be in it, how an object should be created. Class makes its blueprint.
Class doesn't occupy any special space in memory. But whenever we have to make an object from a class, let's suppose this is our object 1, this is our object 2, this is our object 3, so these individual objects, they occupy space in memory. So, the memory allocated to them, memory allocated means space allocated for the data members in the computer. If you want to initialize the data members with certain values, then we use constructors. If we don't make a constructor ourselves, then C++ automatically makes a constructor for us.
For example, in the teacher class, we haven't made any special function constructor. So, how is the constructor called for this object? Because the compiler automatically makes a constructor.
So, either the programmer makes a constructor or the compiler makes a constructor. So that's why as a programmer we should also know how to make our own constructors. Now there are some basic properties of a constructor. First we understand them and then we know what exactly is the meaning of initialization.
Constructor is a function whose name is same as the class. And there is no return type of constructors. Meaning?
If we want to create a constructor for our teacher class, then we will come here and make a function. The name of this function will also be teacher. But what is this? This is not a class, this is a function. And this function has no return type.
Return type is not void, string is not there, int is not there, bool is not there, float is not there, nothing is there. It is just a function. And in this way, we can see out in this function. Hi, I am constructor.
In this way, we will make this simple and lovely statement cout. And what have we made? We have made this a constructor. So this time, when we will create our teacher t1 object, so when this line will execute, So, as soon as we create an object, this constructor function will be called.
So, let us run our code. So, first of all, this line will be printed as Hi, I am constructor. Which shows that if this line was run in the main, then the constructor line will be printed. If we make one more object here, teacher t2.
So, two lines are printed, Hi I am constructor, Hi I am constructor. Because for the first time, the constructor is called for the object, then it is called again. So, it will print the same line again and again. Now, what does initialization mean inside the constructor?
Initialization means that you assign value for some data members first. For example, we want that all our teachers, for all of them, the department should be set first that all these teachers are from the computer science department. So if the value of department becomes computer science for every teacher, then we will not have to set that value again and again.
Automatically, as soon as the object is created, the department will become computer science. So if we come here in the main function, then here we will not write t1.department is equal to computer science. And still what we will do, we will make cout t1.department, and then we will see what value we will get.
So in the call, we created teacher t1. After that we assigned some values but did not assign department. But what would the constructor have done?
The constructor would have automatically assigned department computer. So when we print t1.department, then in output, Computer science will be printed. So what we did is we initialized the department's value in our constructor.
Now the constructor function is not like we can call this constructor function separately anytime. Constructor function is called only once when our object is created at the time of object creation. So constructor is only called once at object creation. And we don't have to do extra work to call the constructor. Constructor is automatically called.
Now with this generally our classes are Constructor is always declared as public. Constructor should never be made private. Because Constructor is being called by the main function internally automatically. So, the main function will not have access to private members. That's why Constructor is always declared as public.
So, we have seen these three properties. Along with this, Memory allocation happens when Constructor is called. What does this mean?
For example, We made a class. A simple class. Let's call it A. In A class, we have made an integer x.
So, in this way we have made an integer x. Now, we will make an object of A class. This is object 1 of A class. This is object 2 of A class.
So, when we are making this class, then as such, no space is occupied in memory. When will space be occupied? Space occupied means memory allocation will happen when we will create an object. So, as soon as object 1 is created, let's suppose this is the memory of our computer.
So in the computer memory, object1 is given some space and all its variables are stored in it. For object1, we have x, this variable. So for this variable x, space will be allocated here. When we create object2, object2 will get space in memory and space will be allocated for object2's x. In future, if any other objects of A class are created, So, for them, a separate space will be allocated and in this way, the memory allocation is for objects, not for classes.
And when does it happen? It happens when our constructor is called. Whether it is a compiler constructor or our constructor.
So, the memory allocation work of objects is done internally by our constructor. Now, whenever we study constructors, there are three types of constructors that we study in C++. One is our non-parameterized.
constructors. Non-parameterized constructor, it might seem complex to hear, but it means that it has no parameters. Like a function has no parameters. Now if we see this constructor, this constructor is a non parameterized constructor because it does not have any parameters in parentheses.
The second type of constructor is parameterized constructor which has some parameters and the third constructor is copy constructor. Now let's talk about parameterized constructor. We have seen non parameterized. If we make another constructor like this and define some parameters in it.
For example, we have just done department computer science. But what we will do is, as soon as an object is created, instead of assigning these values separately, we will take all the values in the same line. That is, we will take a parameter here, string n, which will be short for our name.
We will take a parameter, string d, which will be short for our department. We will take a parameter, string s, which will be short for our subject. And it will be short for our subject.
parameter le lenge double salary jo amari salary ke li short ho jayega. To hum yaha par jo bhi hamara name hai usse n ki value assign kar sakte hai, jo bhi hamara department hai usse d ki value assign kar sakte hai, jo bhi hamara subject hai usse s value assign kar sakte hai and we can assign salary wali value using this. So, what happened in this constructor?
Four parameters came in this constructor. And here we are doing the initialization of the object again. So, this is a different constructor and this is a different constructor.
Let's comment this out for once. And this time when we will create our object, we will not give all the values separately. This time what we will do is, we will create t1 and here we will pass all the values by putting parentheses. Which value does T1 constructor take?
First of all, it should have 3 strings of name, department and subject. So, we will send Shraddha in name. In department, let's send computer science. subject ke andar hum C plus us send karenge aur salary ke andar hum apni value ko send karenge.
To is tarike se single line ke andar hi saari values hum constructor ke andar pass kar sakte ek parameterize constructor ke andar aur wo values initialize ho jayenge. Aur ek aur yaha par hum function mana lete hain. Let's call this function void get info.
What will getInfo do? GetInfo will see out all the information of our teacher. So, the name of the teacher, or for now, let's input the name, and let's input our subject. So, subject is done, and this will be equal to subject.
So, we will assign values for our teacher and we will call t1.getInfo. So, we did nothing, we declared a parameterized constructor in which some values will come, those values will be assigned to the object and then we will print those values. Let's clear this and rerun our code.
So, those values are assigned for us and the value of our name and subject is printed for us. So, in this way we can create non-parameterized constructors also. Now, in one class, multiple constructors can also be there.
Given that the parameters of those constructors are different, means teacher and teacher, these two same name constructors can be in the same class, only their parameters should be different. For example, here there is no parameter, here there are 4 parameters. We can make one more which has 3 parameters, we can make one more which has different types of parameters.
So, when we create two such constructors in the same class, then we will not get any error. Automatically, It will be detected for us that we have sent 4 values here and we know the type of those values. So we know automatically this constructor will call and this one will not call. This phenomenon in which multiple constructors can be present, their name can be same. Only their type will be different.
The different phenomena or concepts are called as constructor overloading in programming. And constructor overloading is an example of polymorphism. We will study polymorphism in detail later. But polymorphism is an example of constructor overloading. In our classes, we get to see constructor overloading in many places.
So, till here we have studied non-parameterized constructor and parameterized constructor. Now before talking about copy constructor we are going to talk about one more special concept which is our this pointer. In C++ this is a special pointer that points to the current object.
For example we are calling a function of our object 1. Now if we want to refer the properties of this object then either this function can access those properties by writing property. So here we already know that this property This is the property of this object. Or there is another way to write this object, we write this and then we put the arrow symbol.
How do we put the arrow symbol? We write hyphen, i.e. dash and then the greater than sign and then we write this property. We are saying this property also means that we are talking about the properties of this object. Now let's see an example of why this pointer is needed.
For example, here we have made our teacher parameterized constructor. Now this parameter inside this constructor, we don't want to keep the name of these parameters in short like this. We want to give complete name to this string, name of department to this string, name of subject to this string, name of salary to this variable.
So here basically we have to write name is equal to name. Whose name is this left one? This left one is the name of our class. In fact, all these properties, we will write these properties.
If you want you can write it in the top. So here when we are writing the name in the left, writing the name in the left means that we are talking about the object's name, the object's name property. And the name on the right, we want it to be our parameter. But when we write a statement like this, it will be confusing for our constructor and compiler. Because we are not able to understand which is the object's property.
So whenever we want to show the object's properties, we can show them using the this pointer. So if we want to show that the left one is the name of our object, then we can write this hyphen greater than. So this is our arrow symbol, this is the arrow operator.
And in this way, we will know the left one is the property of our object. For department also, if there is department in left and department in right, then we will write this department in left. This is the department of object and this value of department in right is the parameter of our function, this is the parameter of our constructor.
Left is the subject of our object and this subject is the parameter of our constructor. Left is the salary of this object and the salary value of the right is the parameter of our constructor. So in this way we can use this pointer to access the properties of the object.
Now if we save this then there will be no error in our code as such because it was the complete syntax. Now if we run it then we are going to get the same output. Now how does this pointer work exactly? If any object is created in C++ For example we have created an object of a class So what does our this do?
Our this is a special pointer If this is our object and it has occupied the entire memory of this object So what does this do? This points to this memory That is if the address of this memory is equal to 100 So this is also a variable in itself Which stores 100 inside Because what is this? It is an automatically created pointer which always points to this object, the calling object which is calling the function. So, what is the calling object in our constructor? The calling object in the constructor is T1 for which the constructor is being called with all these values.
So, before understanding the concept of this, first of all, our basic C++ pointers knowledge should be a little clear, only then we will get more clarity. So, if you have not read C++ pointers yet, then you have to read their basic sums first. Because pointers are really really important in C++ because majority data structures are using pointers somewhere.
So, whenever we declare a pointer in C++, let's suppose we declare an int star ptr which is storing the address of an integer x which had 10 stored in it. So, if we ever want to access the value of this x, then we can either write x or we can write star ptr. This star is our dereferencing operator in C++.
There are many functions of star, it is used for multiplying and also as a dereferencing operator. Dereference means in pointers, the value that the pointer is pointing to, if the value of x is pointing to 10, then star pointer means we are talking about this 10. So if we write star this, this is the value of star. We are talking about our object. And if we want to write object.property, then we have to write star this dot property. Now this star this dot property, there is one more easy way to write this in C++, which is this arrow operator.
So arrow operator is not such a new thing. We are showing this complex thing of pointers, just by showing it with arrow, so it looks a little easy to read. That's why.
with which we are using arrow operator. Rest the concept is being used which we use with normal integer pointer character pointer in CPSS. So it is not a very tough concept, it can be tough when we have not studied pointers.
So for good interview preparation after watching this whole lecture, we can revise the pointers. Now next we are going to talk about our third type of constructor which is called the copy constructor. Copy constructor works exactly like its name.
That means its work is to copy objects. It takes the properties of one object and copies the other of that object. So copy constructor is a special constructor.
which is used to copy properties of one object into another. Now if we don't make a copy constructor by ourselves, then C++ makes a default copy constructor for us by itself. For example, we made a teacher with all these values. Now let's suppose we make a teacher T2.
And in T2, in the constructor parameters, instead of passing all of these values, What we will pass? In fact if you are using Visual Studio code, VS code, then if you hover over it, then some suggestions also come here. Like here one suggestion is coming, you can pass a constant teacher address.
Means we can pass reference of any other teacher object. So we are going to pass the same thing, that is we are going to pass T1. Now here as such we have not written any such constructor, which takes any other object as a parameter, but still this code will work. And for T2, when we will do get info, So let's see what will be printed.
Let's comment out this. What we have done here is, we have written information for T1. We have passed T1 from T2 and have given information for T2.
Now we have never defined T2's information. But still this code will print the correct output for us. Which is T1's information. So what happened here, when we wrote this type of syntax. So here for us C++'s default copy constructor was invoked.
Was invoked or was it... Call happened, you can say anything but here basically default copy constructor was called. Now how does copy constructor make copy?
Let's suppose we made an object t1. Let's suppose this is my object t1. Now in t1 there must be some value of name which must be stored. Let's suppose here Shraddha was stored. Some value of subject must be stored, here C++ was stored.
Some value of our department which was stored. We had kept computer science department. Some value of salary which was stored. we had kept 25k salary now as soon as we write this single statement that is to invoke copy constructor similarly in memory this whole object is made and its exact copy is made and its name is made in memory t2 so in this way a copy is created now if we want we can make our own copy constructor nothing to do in making copy constructor just here a third type of constructor let's call it the constructor copy constructor, we can make it, we will name it teacher and inside this, let's remove this non-parameterized constructor and inside this teacher constructor, basically we will have an object of teacher type, so we will have an object of teacher type and we pass this object by reference, now what does pass by reference mean inside C++, let me also write this.
This is pass by reference. It means either if you had read call by value, call by reference in C++, while reading functions, then you would have understood there. Otherwise, in the concept of pointers, we are generally looking at pass by reference.
Otherwise, pass by reference means that the object we are talking about here, is not a copy of the original object, it is the original object. It means that the address of the original object is passed here, a copy is not created. So, whatever changes will be inside this constructor, they will reflect in this original object.
This is what it means. But we don't have to make any changes in the original object. Let's call it original object. This is the original object of the teacher. And what we will do is, this's name is equal to original object's name.
Dot name. This's department is equal to original object's department. This's car.
Subject is equal to original object ka subject and this ki salary is equal to original object ki salary. Let's save this once. Toh abhi tak hamare paas hamare default copy constructor hota tha.
Ab humne apna khud ka custom copy constructor bana liya. Aur yahaan pe guste hi hum see out kara denge. I am custom.
copy constructor. So, this way we can see out something, so that we know that our copy constructor has been called. And this time we will run the same statement. So, this time not default copy constructor, this time our custom copy constructor is going to be called. Let's see.
So what happened here? I am custom copy constructor and after that all our values got copied in T2. So when we called get info for T2, it printed our information.
So basically the work that the default copy constructor used to do, we did it in our own copy constructor. Now whenever object copies are made, there are basically two types of copies that can be created in C++. One copy is called shallow copy.
and we have one type of copy, which is deep copy. And there is a slight difference between the two. Shallow means in English, the one which is less deep and deep means the one which is more deep. Shallow means from top to bottom. So basically, in general, the default constructor that C++ makes for us, or the copy constructor that we have written, all of these make a shallow copy.
Shallow copy, if you have normal properties then there will be no problem in making shallow copy. In majority cases we make shallow copy. Shallow copy means that it picks up all the values of all the members of an object and copies them in another object. For example, as we saw in this case, who did what?
It picked up the value of name Shadda and kept it here. Picked up the value of C++ and kept it here. Picked up the value of Cs and kept it here. And in this way it picked up a lot of values and copied them here.
So here this copy is basically a shallow copy. And in normal cases shallow copy is fine, as such there is no issue. The issue with shallow copy comes when we are doing dynamic memory allocation.
Dynamic memory allocation means when we are using a new keyword to allocate a new memory or when we are using pointers, then we have an issue. If we know that the normal memory allocated, means all the variables that are created, are generally created in our stack memory. This is a basic C++ concept. You must have read it.
And if you haven't read it, then you can read it. Basically, all the functions that are called, like this is my main function, so all the variables that are created in the main function, will be created in the stack memory. If the main function calls fun, then all the variables will be, will be created in the stack memory. But if we allocate any new memory using the new keyword, like dynamically memory allocation is done by C++ in such a way that we have done new int 5, new int 5 means that give me a new memory equal to 5 integers. And this memory is given, it is dynamic, means this memory is allocated on runtime.
Integer function is done, fun function is done, generally the functions are allocated memory on stack, and it is statically allocated, meaning you get the memory in compile time this means that if I define an integer x is equal to 5 in main then this integer x will take memory in my stack x is equal to 5 and it will be created here and when it will be created? it will be allocated in compile time but whatever memory is allocated using new keyword, like I made an array of 5 size using new keyword or if I simply write new int, then where will I get this new int? I will not get it in stack Basically memory has a special area which we call as heap in which it is dynamically allocated and heap memory is called as dynamic memory allocation means dynamically allocated memory is on heap so shallow copy gives us problem when in our code, in our class, in our objects dynamically memory is allocated means in heap, some property of them or there is a pointer pointing towards the property but its values are stored here.
So when we have a situation like this, then our shallow copy gives us a problem. And how does it give us a problem? Let's see an example of that. For example, let's create one more class.
We will call this class as our student class. Let's suppose we have created a student class to store the data of our student. So let's remove our teacher class from the top.
And let's talk about this student class entirely. Student ke paas bahut saari properties ho sakte hai. Isko kuch public properties de dete hai. Ek to student ke paas obviously apna naam hoga.
Aur ek let's suppose is student ke paas hai ek apna CGPA. Student apna naam store kar aata hai aur apna CGPA store kar aata hai. Aur saath ke saath there is also this constructor in student.
Constructor ke andar ek to name aata hai aur ek student ka CGPA aata hai. So we have made a constructor. This name is equal to name.
And this CGPA is equal to CGPA. In this way we have made values. And we will make one more function.
Let's call it getInfo. And what getInfo does is it prints information for the student. See out.
Here it will print the name. So here we will have the name printed. And in the same way, we will print our CGPA.
So, we will have our CGPA printed. So, we have properly created our student class. Now, here we are going to make an object of student class in our main function.
In the main function, we have made an object of student S1. Let's call the student Rahul Kumar. And let's suppose Rahul Kumar's CGPA is equal to 8.9.
So if we want, we can call get info for S1. So our data will be printed for us. The data is printed perfectly.
There is no issue. Now what we want is that just like Rahul Kumar, another S2 student has come in our class. His name is also Rahul Kumar. So we directly want that the data of S1 student should be copied in this S2 student. So what we will do is that either we make a default copy constructor or we can make a normal constructor as well.
As such, there will be no issue. and after that for our student S2, we will call get info so in this case also there will be no issue, all the information will be directly copied to us so till now for student we have invoked copy constructor as default, there was no issue as such we can write our copy constructor ourselves for student we have ordered the original object of student class let's call it object and we have this's name is equal to object's name and this's is equal to object's CGPA. If we do this, then this time our constructor will call. Even in that, no issue will come as such, all the things will remain same.
Now we are just going to do one change. Till now, all the properties we were using, were running on statically allocated memory. All these are being created in stack. this time we will do something about heap heap means for our student this time we will not directly store the value of CGPA we will store a pointer of CGPA which will point the value of CGPA this time it will not be double CGPA this time it is a double pointer which is the pointer of CGPA so this time we made a pointer and as soon as we get the value of CGPA First of all, we have to allocate new memory to this pointer. So, the concept of allocating new memory to the pointer, you must have read this in C++ while reading the pointers.
Otherwise, let's see the process of doing this. To allocate new memory, we write CGPA pointer is equal to new float. So, basically, what was our CGPA pointer earlier? It was not pointing anywhere earlier.
It was a random pointer. Means, in memory, if we had this, CGPA PTR, so CGPA PTR was not pointing anywhere earlier. Now what we did is, we pointed it towards a special memory. And what is this memory? It is a float type memory, in which float type data can be stored.
So this is a new memory, and where is this memory? This memory is inside our heap, because it is a dynamically allocated memory. And now what we did is, where CGPA pointer was, where it is pointing, we dereferenced it and stored our CGPA in that place. Means the place where CGPA pointer was pointing, the memory address where it was pointing Let's suppose if its address is equal to 100, then CGPA pointer is storing the address equal to 100 So by going to this address of 100, we have stored our 8.9 CGPA there So this means that the work is the same, we will print the information as such we will not get any error But this time CGPA does not exist, so what we have to do is We have to find the value of CGPA by dereferencing from CGPA pointer. This is a small change that we have to do.
So let's summarize the whole thing once. This time, we have made a pointer by not storing the value of CGPA directly. First, we pointed the pointer towards the new memory.
After that, we stored the value of CGPA in that memory. We don't have to do anything with our copy constructor here. We will do CGPA pointer instead of CGPA pointer.
So, there is no change. and in get information we did CGPA pointer so here instead of new float we actually had to do new double because our pointer is pointing to double so nothing, here our double memory will come means in our diagram instead of float this memory will be typed Double k equal, there will be no more changes than that. Let's save the code and let's run it.
So, we have run it. As such, we have not got any error. Still, the name is Rahul Kumar, CGPA is 8.9. But now, we will see an interesting thing.
Let's suppose, my CGPA is of second student. I don't want to keep CGPA 8.9 for second student. I want to change this CGPA to, let's suppose, 9.2.
So, what we did is, the value of CGPA pointer of S2, or by dereferencing it We will change the value of that to 9.2. That our student 2 has a CGPA of 9.2 and not 8.9. So, let's do both these things. After that, what we will do is, first of all we will get information of S1.
After that, we will get information for S1 again. And let's try to see the change. Basically, we made an S1 student and an S2 student.
We call him Rahul Kumar. We will change the name of this S2 student to Neha Kumar. The first one is Rahul Kumar and the second one is Neha Kumar.
When S1.getinfo is done, the information of student 1, Rahul, will be printed. Then we made Neha's CGPA 9.2. After that when we print Rahul's information again, we will expect that there should not be any change. For Rahul, we did not change anything in CGPA. Here we increased the CGPA of Neha by 9.2.
But when we finally run this code, let's save it and run. So this change comes under our code. Means Rahul's original CGPA was 8.9.
We didn't change anything in Rahul's CGPA. Neha's CGPA was increased. So how Rahul's CGPA increased automatically?
This was possible because of dynamic memory. allocation because of a shallow copy. This problem arises in shallow copy. The value of the pointer you are not even changing, its value has changed.
You were changing the CGPA pointer of S2, but for us the CGPA pointer of S1 has changed. How did this happen? Let's understand the logic behind this.
Shallow copy says that what do I do from top to bottom? I will copy the values from top to bottom. So now let's see which values it copied. Basically we had made our S1 object.
This was our S1 object. In S1 object there was a string. Name. What was inside the name? It was Rahul.
Apart from that there was a CGPA pointer. What does pointer store? It stores pointer address.
So, in memory, let's suppose this is the heap memory. 8.9 must have been stored somewhere in heap memory. On which address? Let's suppose it was stored on 555, the address of 555, 8.9.
So, what did it do? It stored the address of 555. Now, S2 says, make a copy of S1 and give it to me. So, our copy constructor listened to him and gave him a lovely copy of S1. And we named this copy. Now this S2, because it has a copy, and how did it get copied?
This is a shallow copy, shallow copy means the values got copied. This name got Rahul and in CGPA pointer, its address got stored as 555, because pointer will store the address only. But if we think carefully, then we will get to know that my CGPA pointer is also pointing here and my CGPA pointer is also pointing here, because eventually the address is same as mine.
So this problem arises in shallow copy. Now if for S2, if we increase Neha's CGPA, let's suppose we want to do 9.2, then what we will do is go to this address 555, we reached this address in heap. Now what we did is we changed its value to 9.2. So tomorrow when we are looking at its CGPA for S1, then S1 is pointing to 555, so if we go to this address, then we will get its CGPA changed. Even though we didn't want that change, But that change still reflects when we directly assign the value of the pointer.
Or if we don't make our own copy constructor, then also the same problem will arise. If we comment our own copy constructor and think that the default constructor will make the right copy and give it to us. So the default constructor also gives us the same issue.
For Rahul Kumar, the CGPA changed to 9.2. So whether we are making our own constructor directly or we are using default constructor, this issue will arise until we are making shallow copy. So that's why we need our deep copy. What does deep copy say?
For deep copy, we have to write the constructor by ourselves. automatically compiler will not give us the default constructor of deep copy compiler says I will make shallow copy and give it to you, if you want to make it then make it if you want to make deep copy then you have to make it yourself in deep copy constructor what we do is we make copy of dynamically allocated memory like what we have to do to make deep copy for that we will say let's come to original values We will say that if there is a store of 8.9 here, which is being pointed by our S1, then for the CGP pointer of our S2, we will make a new variable. Let's suppose this heap memory is really big.
So what we will do here is we will allocate a new place here. Let's suppose its address is 600. Here we will store value 9.2. And we will store its address 600 here.
So right pointer is pointing to this. And this pointer is pointing to this. Now what happened?
Now deep copy happened. Deep means now by going deep, you copied the heap memory. You copied that too. You made a copy of that too. Now if Neha will change her marks, then Neha's marks will change, Rahul will change his marks, then Rahul's marks will change.
Now there will be no overlap. So generally whenever we have dynamically allocated memory, we prefer deep copy and we write its constructor. Now in this example, how could we make a deep copy constructor? How could we make our own deep copy?
Let's see that. We didn't have to do anything, we had to allocate new memory in heap. This was our copy constructor.
We just had to make a small change in this, that our CGPA pointer, we would have made it new double and then inside this CGPA pointer, we would have just copied this value. Copy the value means, the value that our CGPA pointer is pointing at, we would have stored the same value there, which is stored inside the CGPA pointer of our object. Means in the beginning, this would have been 8.9 and in a different place, we would have also made it 8.9. So, in both the places we make 2 copies of 8.9 and 8.9.
Because copy constructor makes deep copy. Then later in main function we change this one to 9.2. So, we have dynamically allocated the CGPay pointer again. After that what we did? The value which is stored in original, we stored that value here.
Now if we save this and run the code this time without changes in main function. So, what happened this time? This time, the marks of Rahul Kumar.
It remained the same, only Neha changed her marks to 9.2. And if we call s2.getinfo for Neha, then we would get more marks. Before calling Neha, let's change the name of s2..name is equal to Neha. It will be more clear for us. So here Neha's marks are 9.2 and Rahul Kumar's 8.9 is 8.9.
So this is the great difference between shallow copy and deep copy in C++. And this is a very important concept. It is asked in interviews. And this is not just the concept of C++. As a good programmer, as a good developer, you should know.
Because if you work with Java tomorrow, if you work with other programming languages tomorrow, then generally OOPs concepts are such that all over languages are almost the same. We make similar classes in Java and in other languages. So once you have clear concepts in C++, then generally concepts of other languages will also be easy for us.
Next we are going to talk about the concept of destructor. Destructor is opposite of constructor. Like the constructor's work is to allocate memory, that is to give memory to the object. The destructor's work is to de-allocate memory. That is, whatever memory is given to the object, our computer system's memory, remove that memory from there, clean that memory.
So, destructor is also a special function of ours and automatically compiler makes destructor for us when we don't make it. Like till now we haven't made any destructor but still after the completion of main function automatically our objects are being cleaned so, automatically destructor is made for us but our destructor de-allocates statically allocated memory. The same problem that we had in shallow copy and deep copy, if you have dynamically allocated a memory in the object, then you have to dynamically deallocate it. In C++, the memory that we dynamically allocate, if we use a new keyword, then to deallocate it, we have to use delete keyword.
And how do we free the memory? Let's suppose, this is not a concept of oops, but a concept of pointers. Let's suppose this is our heap.
In heap, there is a memory, address is 100, here value is stored as 55. Our ptr pointer is pointing towards this 55. If we want to free this memory, then we write delete ptr. Delete ptr does not mean to delete the pointer. Delete ptr means that the pointer is pointing at the memory, delete that memory. Pointer will remain. You can see out ptr after this.
This pointer survives, it doesn't delete, but the memory that the pointer points to, in the heap, that memory gets deleted. So if in any class we have dynamically allocated memory from new, then it is very important to deallocate it. So what we have done here, here, like our CGPay pointer, we have deallocated memory from new, so it is important to deallocate it. So for this class, it is important to make our destructor. For now, let's make a normal destructor.
What do we have to do to make a normal destructor? Destructor has the same name as the class. If we want to make a destructor of student class, then its name will be student only.
For now, let's remove this copy constructor. Because we have covered this concept. And here also, let's remove all these things. In main function, we have just made S1 student object.
And for that, we have called getInfo. So, this is our constructor. To make destructor, we have to write the same syntax.
we just put a tilde symbol in front of our function. Which we get on the top left side of our keyboard. We call it the tilde symbol.
We put this symbol and let's suppose we have made our own destructor in which we are printing. Hi, I delete everything. So, the work of destructor is to delete things, to deallocate things.
So, we are printing this thing. So, even though we don't call destructor ourselves, but like the constructor gets called automatically, The destructor is also automatically called. In the main function, if our function runs, then what will happen? First, the student object will be created.
Then, its information will be printed. Then, as soon as this main function is finished, the compiler detects that this main function is finished. After that, the memory of the object of S1 will not be needed.
So, deallocate that memory. Delete the object from the memory. So to delete, a destructor will call, so it will print, hi, I delete everything. So when we don't make a destructor, it automatically becomes a destructor. And we don't have to call a destructor separately, it automatically calls depending upon when our object goes out of scope.
Means when our object is not needed in the code. Now inside destructor, Only our normal memory, normal variables are free. To free the new dynamically allocated memory, what do we have to do?
To free this, we have to write delete CGPA PTR. That CGPA pointer, which is pointing towards memory, free that occupied memory. So this is an extra step which we need to take in our destructor. So we have taken this step, so as such our code will not change, it is changing in memory. But when we are reading DSA or MOOPS, we are using C++ single file.
And generally we are using it in a code editor like Visual Studio Code or any other code editor. So here automatically as soon as your code gets finished, all the memory that your code was taking is free. Whether you are using destructor or not.
But whenever we go to the organization level, company level, these things become very important. That's why they are asked in interviews whether we have the knowledge of destructor properly or not. Because if we don't free dynamically allocated memory by writing this delete keyword separately, then many issues can come. One of them is memory leak.
Memory leak means that you have left many memories in heap, now no pointer is pointing towards that memory and that memory can't be used for other work also. Basically, that memory is wasted. So, in this way, not wasting system memory, he humari approach honi chahiye and that is why destructors become important.
Next hum baat karne wale hai about the concept of inheritance. Inheritance is one of the four pillars of hoops. Inheritance vise day to day life mein humne observe ki hogi. Humari jo parents hotay hain, wo kya karte hain, wo humari qualities pass on karte hain to us. To parent kya karta hai, apni jo qualities hotay hain, wo child ko pass on karta hai.
Is process ko, We call this inheritance in general English. And this concept is also called inheritance in C++. Basically, if one class, let's suppose this is a class A, if it is passing its properties to some other class B, then we say that class B is inheriting things from class A.
Inherit means to take, inheritance. So, the properties in class A will come under class B. And in this way, when inheritance happens, in class A, we generally call it our parent class.
Or we call it our base class. And class B, we either call it our child class. Or we call it derived class. Derived means the one that has come from above. So, inheritance is a C++ OOPS concept when properties and member functions of base class are passed on to the derived class.
So, in this way, when things are happening, then we use inheritance. Now, why is inheritance used? Inheritance is used for code reusability.
Code reusability means, for example, if there is a property in class A, Integer X. The same property is used in class B. Now instead of making it again, what we should do is, we should inherit that property directly from class A. Now here I took a very small example of Integer X. But companies have very big classes, which have a lot of properties. Now if you write a lot of properties of code in every class, what is better than that?
You should inherit it. So logically inheritance is very important for code reusability. Once you have written the code, we are directly reusing it. It doesn't need to be written again. So let's see an example of this.
Let's suppose we have created a class person. Person means any person. Now every person will have a name.
Every person will have an age. So what we did for this? We made two public properties. One is string name and one is integer age. So this way we can create our person.
We will get string name in person. and we'll also get age so this string is equal to this name is equal to name and this age is equal to age. So this is our proper person class created. Now we want to make another class student class. What properties do we need in our student class?
First we need the student's name, second we need the student's age and third we need the student's role number. Now we will know that we have already defined the name and age of the student. So we don't need to define it again as such.
We will just define the extra roll number and we will inherit the person. So to inherit the person, we will write colon and here we will write our access modifier. Let's suppose our access modifier is public and then we write the name of our base class.
How does access modifier work here? I mean why did we write public here? We will read about it in detail now.
But basically, there are different modes of inheritance. You want to inherit in private mode, you want to do it in public mode, you want to do it in protected mode. We want to inherit the properties of our person class in our student class in public mode.
So what will happen with this? This name and age, This will come in the student class for us. Now we don't need to define name and age, it is already there.
We will just define the role number. And what we do for once is, for once we remove this constructor and create a simple constructor. Let's suppose this is a simple constructor which is in the person class.
Now it is not parameterized. So what we will do in the student class is, we will define some public property in the student class as well. This is our one.
There can be a roll number and we will define a function getInfo. In the getInfo function of the student, we will print the name of the student. So one will be named, one here we will print the age of the student. So this will be the age and one will be the roll number.
So this will be the roll number of the student. Now one thing to note here is that in the student class, we did not make any property of name and age. Then also we will access name and age in get info and there will be no error. So in main function we make an object of student.
Student s1 and for student s1 s1 dot name is equal to let's suppose Rahul. and s1.age is equal to 21 and s1.roll number is equal to 1234. So, this way we have defined the information. Now, for s1, let's call get info.
Let's save it and execute. Here, semicolon was missing, let's put semicolon. So what happened?
No error came, all the things worked as it is. Even though in student class we did not define any name and age properties. So what did student class do?
It inherited those properties from person and now its functions will treat it like name and age are its properties. Because they are actually its properties. So this way our inheritance works.
So whenever inheritance happens. So all the properties of our parent class now exist in our child class as well. And whenever inheritance is happening and we make an object of child class. For example, if we try to create an object of B class.
If we make an object of B class. So first of all, what happens? First of all, the constructor call of base class is made.
After that, the constructor call of derived class is made. We can verify this too. Like we make a constructor of our derived class, student. And we call this, or instead of derived, cout. Child constructor.
And in the same way, in another person, already we have made a constructor, so here we will simply cout. parent constructor. So, we will verify it.
Constructors are automatically called. So, let's clear this and rerun the code. So, first of all, what happened?
As soon as we tried to make an object of student class here, we came inside student class. Before this constructor is called in student class, it will see that it inherits the person. So, first create the person. So, what will happen before the student? The person will be called.
So, the constructor of the parent class is called. After that, we came inside the constructor of our student class, that is, our child class. So, in which sequence, in which order, the constructor is called is also a very important interview question. Whenever inheritance occurs, first the constructor of the parent class is called, then the constructor of the child class is called. And opposite happens in the destructor.
Whenever an object goes out of scope, means whenever the memory of an object is deallocated, it is called. So first the memory of child class is deallocated then the memory of parent class is deallocated. And you can verify this by making the constructor of both classes.
Here you have to pause once and make the destructors of both classes. In destructors you have to write child destructor, parent destructor. And then you have to see that when the main function is over then whose destructor is being called first. So that thing will be verified for you.
First base is derived in constructor and then base class is derived in destructor. Also if we from here, let's suppose our... constructor is a parameterized constructor. Parameterized constructor means in person there is no such constructor.
In person there is normal constructor. So parameterized constructor automatically doesn't call because they didn't make compiler. They were made by human, programmer. We made it.
So who will call such constructor? Such constructor So we call basically before our own constructor. Before our own constructor, we will do this by colon.
We write the name of our parent class, i.e. person. And we pass properties in it. That pass string name and pass int age.
So this way before our constructor, the constructor of person class will be called with these values. And we can keep our value for ourselves. Let's suppose if these three values came to the student, then what we have to do with them, one is our name value, one is our age value, and one is our role number value. So we will assign the role number here. This's role number will be equal to role number.
And before the role number, we will send the name and age to the constructor of the person class. So in this way, we can explicitly call the constructor of the parent class. from our own child constructor. Now here, these values do not need to be written like this. Basically, when we define S1, we will write student's name is Rahul Kumar, CGPA age is 21 and the rule number is 1234. So, as such, no error will come in the code.
So, we have to run this. Okay, here because we are calling the constructor, so we do not need to send type as such. If we call the constructor, then it has to pass values only. We don't write type, we have to pass values. Where do we write type?
When we are defining a function, here we are calling the function, the constructor explicitly. Let's run our code and in this way our code has worked in the right way. So this is what the basics of inheritance look like. Here we saw the inheritance, which is basically the inheritance of public mode. But what does mode of inheritance mean?
We have three modes of inheritance. One is private mode, one is protected mode, one is public mode. Basically base class.
Base class means, in our parent class, if there is any private member, then he never inherits. Private properties and private functions never inherit. So for private, whether you are doing inheritance in private mode, in protected mode, or in public mode, private members are never inherited. Public members are inherited in every case.
If you have any public property, then in public mode, in the derived class, that property will become public. In protected mode, that property will become protected. And in private mode, that property will become private. Basically, if we had made the mode private, So, here our string and age public becomes private in this class.
And in that case, if we try to see out in main function s1.name, here parenthesis will not come in s1.name, so if we execute it, then we get an error here that constrained by private inheritance. That we have inherited the properties of the person in private mode, so you cannot access their members in this way in the main function. And third we have is protected. Basically, if we have a private property which we want to inherit, we don't want to give access to outside the class, we just want to inherit it in other classes, then we make these private properties protected. This is what protected means.
They have to pass for inheritance only. If they don't want to do anything else, then make them protected. So all the protected properties, if they are passed in public mode, they remain protected. If they are passed in protected mode, they remain protected. And if they are passed in private mode, they also become private.
So whatever property you want to inherit, whatever you want to keep private, we simply make it protected. So if there are protected members in any class, then that class can access them. Along with that, the derived classes of those classes can also be accessed.
No matter what mode you have performed inheritance in. Now these are modes of inheritance. Apart from this, there are also types of inheritance. The first type of inheritance is single inheritance.
When we pass on properties from one parent class to one base class. Like what we did. We made our person class. Person class passed on properties to our student class.
So, the example we saw here of person and student, this example was an example of single level inheritance or simply single inheritance. Apart from this, the second type of inheritance is multi-level inheritance, in which inheritance is going on at many levels. For example, one is our person class, one is our student class and one is our graduate student class.
Graduate students are basically like M.Tech students or Ph.D students who are additionally teaching something. So, properties are added in person, name, age, role number. Now, grad student has name, age, and role number. Grad student is also doing research on some topic. So, his research area or topic is added.
So, we can add an extra property in it. So, inheritance can run at multiple levels in this way. If we convert it in code, So it will look something like this. This is our person class.
Let's remove this constructor from here. This is our student class which is inheriting the properties of person class and inheriting in public mode. So this student class has only one extra thing, rule number.
So this is our person class. This is the student class which inherits the properties of person class. And this is our one more class. Grad student. Which inherits whose properties?
Which inherits student's properties in public mode. Now student had person's properties. So person's and student's properties came in grad student.
Let us correct this spelling. Grad student has one more extra property. Which is basically string.
Research area. So, this class sent properties to this class and this class sent all its properties to grad student class. Now, if we make an object of grad student class, grad student S1. For S1, let's suppose we define the name to be Tony Stark.
For S1, let's suppose it's going to be research area. maybe quantum physics is the research area and if we are doing cout s1.name and cout s1.research area, so these two values we have to put a semicolon here. These two values will be printed correctly for us. Even though in grad student, we did not define any name property.
And it has been inherited from student. But where did it come from student? It came from person class. So this way our inheritance works on multiple levels.
Next type of inheritance is multiple inheritance. Multiple inheritance happens when one child class inherits properties of two parent classes. For example, there is a class called student.
Student has his own role number. Student has his own name. There is a class called teacher.
Teacher has his own subject. Which subject does he teach? Plus, he has some salary.
Generally, in our colleges, as such, there are no TAs in Indian colleges, but our M.Tech or Ph.D students come to teach us this subject. I don't know about other colleges, but our M.Tech or Ph.D students used to come to teach us. So, they had a specific subject and they had a specific salary from the colleges.
Along with that, their role number and name is there because they are students. So, TAs are basically those classes which students and teachers... both properties are inherited. So how can we do inheritance in this way? First, let's make a student class for this.
So this is a normal student class. In which one we have name and one we have rule number. In the same way we will make a normal class, i.e. teacher class.
What does teacher have? Teacher has one subject. So we keep everything public for simplicity. One string is subject. And one teacher has salary.
So double type key, we have a salary. So if we write in class, TA class banani hai to isme agar hum dono values ko inherit karna chaate hain to hum likhte hain ki public mode me student ko inherit karna hai comma public mode me hi hum teacher ko inherit karna chaate hain to alag alag classes ka hume alag alag mode of inheritance batana padta hai aur sab ko hum comma se separate karke likhte hain to TA class student class se bhi inherit kar raha hai aur teacher class se bhi properties inherit kar raha hai aur TA ke paas apni hum kere hain as such koi property nahi hai ye bas inhi dono classes ki properties leke hai So this way we can make TA. Let's try to create a TA here. TA T1. The name of T1 will be again Tony Stark.
And the subject of T1 will be maybe engineering. Even though engineering is not a single subject. Let's see out TA.name. And in the same way we will see out TA.subject.
Save it, clear it, run it. So values are normally printed for us. No error has come, means things have worked properly. So here, what is this? This is an example of multiple inheritance.
Next type of inheritance is hierarchical inheritance. In hierarchical inheritance, multiple child classes are inheriting from the same parent class. For example, person class. Every person has their own name.
Every person has their own age. Now one will be a student who will get an extra roll number and one will be a teacher who will get an extra subject But both will remain as persons so both can inherit the properties of the person This is going to be very simple to write Will you make a class Person? Classes are always named with capital letters.
For consistency, there is no such rule. But for consistency, generally, almost in every language, not all, but in majority languages, classes are named with capital letters. So, string name is there, integer age is there, in student class, we have a rule number, and what is student class doing?
It is inheriting a person in public mode. What is teacher class doing? In public mode, the person is being inherited. The teacher has its subject.
So, this is basically an example of hierarchical inheritance. For this, we can verify our teacher, student or person by making an object of any class. Next type of inheritance is our hybrid inheritance. Hybrid inheritance is basically where anything is going on. It is a mix of all types of inheritance.
For example, we have a person class. Did the student inherit properties from the person class? and teacher has inherited the properties. Now the student, the grad student is inheriting the properties and student and teacher both have properties that a TA class is inheriting.
So what happened is mix of all categories happened. So this is basically hybrid. Hybrid inheritance is called. And you can implement this thing if you want. Although it's not going to be very difficult.
What we have studied till now, this is all its mix. Now, next we are going to talk about the third pillar of OOP which is called Polymorphism. And Polymorphism is a really interesting concept in OOPs. Polymorphism means, it's made up of two words, poly and morph.
Poly means multiple, a lot of them. Morph means forms, a lot of forms. Meaning, when our object has ability, that it can act in different forms, can behave in different forms, depending on the context. That is called polymorphism.
The most classical example of this, which we have already seen, is constructor overloading. What did we do? Over loading.
What we did? We defined two constructors in one class. Like.
Let's clear all of this. And let's create a very simple. Class called. Student class.
In student class. We define two constructors. Let's keep two public.
First we define its student. Only name. One constructor of student. This non-parameterized constructor, let's make it see out in this.
Non-parameterized constructor. And here let's write student. And in this constructor, our name will come.
And we will say this name is equal to name. Which constructor will be this? Let's make it see out in this. parameterized constructor. So, what we did is, we made two constructors and both have the same name.
So, when we make an object of student class in the main function, student, s1, so how will we know which class's constructor should be called? Basically, if you did not give any parameters, then what will happen automatically? Non-parameterized constructor will be called. Let's see how. Ok, I have defined name string.
It should be string name. Non-parametrized constructor called. But if we take parameters here.
I have taken Tony Stark. So, this time parameterized constructor call will be done. So, depending upon the context, context means how it is being used.
On the basis of that, our object can change its form, our object can decide which constructor call will be done. So, this is called constructor overloading, which is an example of polymorphism. So, in polymorphism, this is what is happening generally, that you define multiple things, multiple things have the same name.
But still we get to know which call will be made Why? Because internally context matters a lot So polymorphism is of two types One is compile time polymorphism One is runtime polymorphism In compile time polymorphism, we get to know what output is going to come In runtime polymorphism, we decide on the runtime what output is going to come Like compile time polymorphism has an example Constructor overloading, which we have just learnt. Now, first of all we will learn Compile-time polymorphism, then we will learn Runtime polymorphism.
We have seen one example of compile-time polymorphism. The second example is function overloading. For example, in constructor overloading, we were making two constructors.
What were the names of both? Both names were same. What were the parameters of both?
The parameters of both were different. What was the difference between both? There was a difference in the parameters.
Similarly, function overloading means that in one class, in a single class, if you define two functions and both the functions should have the same name, Only if the parameters are different. Here one parameter can be there. And the other can be 0. So when the parameters are different.
When the number of parameters are different. Either you make the number different. Or you make the type different. Even if you make the number different.
will be different, if you will make the type different then also it will be different. So, then what happens? Then we get implemented function overloading.
So, when someone asks you what is function overloading? Function overloading is an example or an implementation of compile time polymorphism. How is compile time polymorphism? Compile time polymorphism is statically done.
It is done at compile time only. And function overloading is when we are defining two or more functions with the same name in the same class. but they only differ in terms of their parameters. Return type can be same or different, it doesn't matter, it only matters with our parameters.
So, let's see an example of this. For example, we create a class called print. Our print class's job is to print things.
It will print the integer, it will print the character, it will print the boolean value. So in this print class we have made two functions. One is our show function. Let's call it void show.
Which takes integer x and makes it show. Show means it makes it print. Let's write integer here.
and here we write our x and similarly we have made one more function, we will keep its name also as show but what it does is it takes character ch and this makes ch show. Now, in print both functions have same name but because both have different parameters one has parameter x and other has parameter character so when we make print class object print p1 and call show for p1 with let's suppose sum value 101 So it will automatically detect at compile time that this function is going to be called for us. Because what is the context, what is the usage? It is the usage of integer, so the integer function will be called. Here if the usage of character was, for example, our character was ampersand.
So here character ampersand would have been printed. So depending upon the context, what is the same thing doing? Same thing is taking different forms.
So this is called polymorphism and the direct definition of polymorphism which is written here, you have to remember that for your interviews. So we have discussed two examples of compile time polymorphism. One was constructor overloading, one was function overloading. Similarly, there is another example operator overloading. What happens in operator overloading?
Basically, the same operator is used in multiple ways. For example, if we write int x is equal to y and y was also an integer. is equal to 10. So we can say that in x only 10 value has come.
So where this operator is used? This operator is used for this integer. But we can also write strings, string a is equal to b.
If b is a string, b is equal to abc. So what value has come in a? A, b, c value has come. The string library which we import here. What does it do internally?
It internally overloads this equal to sign. It adds an extra functionality in it. What does equal to mean for string? What is it?
Make a copy of this string in this value string. Overloading is going on here also. You can properly do operator overloading in C++.
We will not go deep dive in that. I am giving you this as a homework problem. We have seen constructor overloading. We have seen function overloading.
Two examples are sufficient for compile time polymorphism. But if you want to go deeper and read, then you can read up more about operator overloading in C++. Generally, if you overload a plus operator or a multiply operator, the concept will become really really clear. Second type of polymorphism is run time polymorphism.
Run time polymorphism is basically dynamic polymorphism. And it is implemented on run time. The most classic example of this is function overriding. Overloading and overriding, differences are often asked in both. What was there in overloading?
In one class, we were making two functions. Overriding is dependent upon inheritance. Wherever overriding has come, you should think of inheritance. Overriding means when parent and child Both contain the same function with different implementations.
This time parameters etc. can be same. Just implementation should be different. Because now there is a parent class, a child class. Here also the same function will be there.
Here also the same function will be there. So depending upon which class you have made the object. On that basis it will be decided which function should be called. And it is decided on run time.
So in this case we say. Generally our parent class and our child class. So it is. Generally if you make an object of child class, then the function of child class is called and if you make an object of parent class, then the function of parent class is called. So in this case we say that the function of parent class is overridden.
The function of child class overrides the function of parent class. Overriding means it has more priority. For child class, the function of child class has more priority. Let's see an example of this. Let's create a class called parent.
This is parent class. Let's clear this. In parent class, let's suppose there is a function called show.
What does show function do? Show function does nothing, it prints parent class. And there is a class called child class.
Or instead of show, we can call it get info. What does this do? This child class publicly inherits parent class. So it is publicly inheriting the parent. And in this child class also there is a function called getInfo.
And the getInfo function of this is printed by the child class. Now what we did in the main function? In the main function we made an object of child class C1. And for C1 we called getInfo.
So when we call getInfo for C1, here we add void extra in front of the name of both the functions. So when we call getInfo for C1, we get a child class print. In this case, the child class function overrides the parent class function.
Whereas, if we make the parent class P1, and call get info for p1, then what happens here? Get info for parent class gets called. So this way we implement function overriding when our parent class and child class both have same name, same function but different implementation.
Now one more second example of runtime polymorphism is our virtual functions. There are some special functions which we can make virtual functions. If you write virtual in front of any function's name, then it will become a virtual function. Virtual functions are basically member functions, which you expect to be defined again after derived class inheritance.
So let's suppose we can make a function void hello, and what does this function do? This function cout hello from parent. This should be from and we can write this as virtual.
Now because we made it virtual, our expectation is that child class should re-implement it. To re-implement, we have to write this function again and we don't write it as virtual in child class. And here we can write hello from child.
It works almost like overriding. Like here if we make an object of child class and call c1.hello for child class. So, our this function will be called.
Here will come hello from child. So, our virtual functions have some properties. Virtual functions are dynamic in nature. They are defined by the keyword virtual inside a base class. And they are always declared with a base class and overridden in a child class.
We write virtual in base class and normally write function in child class. A virtual function is called during runtime. Not in compile time, it is called during runtime. So these are some special properties which we can remember for virtual functions.
So here we have completed our polymorphism. We have seen compile time polymorphism, function overloading, constructor overloading, operator overloading. And we have seen run time polymorphism with function overriding and virtual functions. Next concept which we are going to study is called abstraction.
And we have already written the code of abstraction. Now we will know that the code which we have written was of abstraction. Abstraction is Hiding all unnecessary details and showing only the important parts. The easiest way to implement abstraction is our access modifiers.
What do we do with access modifiers? The unnecessary detail or sensitive detail that we have to hide, we make it private. And the important things that we want to show, we hide them. we make them public.
And those who want to keep private but those who want to inherit we make them protected. So access modifiers are one of the ways of implementing abstraction. When we use access modifier in any class it means we are implementing abstraction.
Abstraction means not only hiding sensitive information it also means that important things are visible. So like we have term was data hiding. We use private for data hiding.
So what is the difference between data hiding and abstraction? Data hiding only hides. Abstraction hides and shows important things.
So access modifiers or access specifiers can be called. They are a way of implementing abstraction. There is also one more way of implementing abstraction. Those are our abstract classes.
If we have written any class, like here, Let's suppose class A, if we write abstract keyword after that, then it becomes an abstract class. Now what is abstract class? In English, abstract means a thought.
So this is a class which is just a thought. To say thought means, the real work of class is to create objects. But abstract class never creates any object.
What does this class do? This class becomes the blueprint of other classes. For example, what is a normal class? Different objects are created from a normal class. This is object 2, this is object 3. So, a class forms a blueprint.
It tells the code what the objects should look like, what properties and member functions should be there. What does an abstract class do? An abstract class is made only for inheritance. And it has no object.
This just tells us how other classes should be. These classes which inherit abstract class, what properties and functions should be implemented in them. So abstract class is like a blueprint for other classes that are going to implement it. So there are some properties of abstract class.
Abstract classes are used to provide a base class from which other classes can be derived. An abstract class becomes a base class from which only inheritance of derived classes is happening. They cannot be instantiated.
Instantiated means their objects cannot be made. Objects in technical term. We call it Instance.
Instance, wherever the word appears in OOPS, it means we want to call it an object. And these classes are meant to be inherited. Abstract classes are typically used to define an interface for derived classes. Basically, an layout, an interface, a template, a blueprint are used to define an abstract class.
For example, we made a class Shape. Now, Shape is... If we want, it should be possible to draw every shape.
But until we know what our shape is, whether we want to draw a circle, a square, a rectangle or a triangle, will we be able to draw any shape? Because shape can be anything. So if we have made a shape class, then we cannot implement its draw function exactly.
So what we have to do is, we have to make another class. Let's suppose we have made a circle class, which is... shape class to inherit and then in this circle we will implement the draw method to draw a circle.
So if we have circle class then we will clearly know that we have to draw a circle. So in this shape class we cannot make any object of the same shape, we can make a circle, we can make a square, we can make a rectangle. So what will we make of the shape?
We can make the shape abstract. So the shape is an idea. Whether you make a circle, square or rectangle class, there should be a draw function in all classes.
We can see the code here. So we have made our class shape. Now we have to tell what functions should be there in this class.
So there should be a draw function in it. But we don't want to implement draw here because we can't draw any shape. We can draw a circle, a square but not a random shape.
So what we do is we make this function virtual. and we assign it a value of 0. This line means that in all the shape classes all the child classes a function named draw should be implemented so what we did is we told it a template, a blueprint and this function we call it pure virtual function Pure virtual function is what we call it, whose value is assigned as 0 and with it the keyword is virtual. And whatever class has pure virtual function in it, what does it become? It automatically becomes an abstract class.
Now this class has automatically become an abstract class. Meaning if we try to make an object of this shape class, then we will get an error. What error will come?
Variable type shape is an abstract class. You cannot make objects of abstract class. shape ki object nahin bana sakte hai. Par shape ko dusri classes se inherit kara sakte hai. Jase circle public mode mein inherit kar lega hamari shape ko.
To wo function implement kar lega. Void. Draw. Isse implement kar ke ham see out kar denge. Drawing a circle.
So, here we will make an object of circle C1 and call our draw function from C1. Let's put two semicolons here. So, drawing a circle has been printed. In the same way, if we want tomorrow, we can make a square class, rectangle class, square draw, rectangle draw.
But we cannot make an object of this class because abstract class's work is just to give an idea. Its work is that it is just giving a blueprint that which things should be in our base class and which things should not be in our base class. And the last important concept about which we are going to talk is static keyword. Static is a very important keyword which is used in C++ OOPs and is being used again and again. We can use static in two ways, either we can use it with variables or we can make our objects static.
If any variable becomes static in a function, So for that function, that variable is created only once and initialized only once for the lifetime of the program. For example, let's create a simple function void func. What we will do in void func is, we will call it fun.
In normal function fun, we have made an integer x is equal to 2. And what we are doing every time is, we will make x is equal to 0. and we are couting x every time and then we are doing x++ so here we are doing couting the value of x now if we call fun once then what will be printed? x is 0 so what will be the value of x? 0 only then it will become 1 but then we will get out of this function so we will get 0 printed this is 0 If we call this function again, or let's suppose we called this function three times, once, three times, then every time the output will be the same.
Zero will come. Because as we are calling the function, similarly what is happening is, in our call stack, our fun function is coming, for that x variable is getting created, zero. Then it is getting deleted again. Then again we are calling it, fun function x is equal to zero.
Then again it is getting deleted, then again in the call stack, fun x is equal to zero. Things are happening like this. But whenever we make this integer x static, with the static keyword, So it is a magical thing. What is magical?
Now this x is not being created here. This x is being created separately. And now even if this function call is removed from here. But this x will remain in memory. And if you call the function again.
Then this time in this x, value 1 will be plus 1. In this x, value 2 will be plus plus. So in this way, its values will keep increasing. This statement. What was happening earlier? With every function call, this one.
statement was running repeatedly. This time this initialization statement will run only once and the rest of the code will run repeatedly. So once in memory x is equal to 0 is created and fun is called. So x has 0 value.
Then we have made x plus plus to 1. Then again fun is called. Then x is printed. So 1 is printed and then 2 is printed.
Then again fun is called. Then if we print x, it will be 2 and its value will be internally 3. We can see this even while it is there. x is equal to 0, x is equal to 1, 2. Because this time x is not destroying again and again. This time x is made once, so it persists in memory till the lifetime of the program.
And static variable, if we make a variable static in a class, then they are shared by all of the objects of the class. For now, let's suppose, If we have made a class, in class a, if we make a variable int x and make a function in it, increment x, what increment x does is increase the value of x by 1. This is what increment x does. So if we make an object of a class, what is this object doing?
We are c-outing the value of x from this object. So let us see out object.x. Then we called increment x for object. And again see out x value.
So our x value will normally update. X value will be 0 first then 1. So it will update like this. Okay we have to initialize it with 0. So object.x has garbage value now. So we will initialize it with 0. First it will be 0, then it will increase and then it will be 1. Now here with object 1 of A, we have created an object 2. Here we create object 2 of A. And what we are doing is, for object 1 we have kept the value of x as 100. And for object 2, we are keeping the value of x as 200. So when we print x for object 2, we should have 200 printed.
Normally for object 2, we should have value print 200, object 1 value print 100. So this way normal things will work. So normally all our properties, if we made an object, object 1, then x will be made separately. If we made object 2, then its x will be made separately.
But if we had put static in front of that x, then for all the objects, only one x would be created. What does x do? X is a separate variable which is created separately and all the objects share that X.
So whenever we make some updations in X, like 100 to 200, 200 to 100, it reflects in all the objects. The objects which we make static in the code, they exist till the lifetime of the program. Generally the object exists according to its scope, that if there is an object here, it will remain till here.
For example, let's create a class called ABC. In the ABC class, one is our constructor and one is our destructor. So, one is ABC, let's remove the constructor. And from here, one is our destructor. Now, if we make an object of ABC class.
Where did we create the object? Instead of creating the object here, what we will do is, if true, then we will create the object here. We have created an object of ABC class here.
So, normally what will happen is, an object will be created here. Then we will see out the end of main function. So, if an object is created inside the block, then as soon as we go out of the block, our object will also get deleted. So, first the object is being constructed, then the object will be destructed.
Then our main function will end. So, in normal cases, this is how our code works. Let's save it. and run. So in normal cases, first constructor comes, then destructor comes, then end of main function.
But if we create this object here with the static keyword, what will happen in that case? In that case, first constructor comes, then main function ends, then our destructor is called. Means whatever object you create with static keyword, it will run till lifetime of the program.
and till our main function i.e. program doesn't get finished till then it will persist in our memory. So in this way our static keyword usage happens in three different conditions. Apart from this if you want to know more deeply you want to explore more concepts in OOPS then there is also this concept of friend function and friend class which you can go and read as a homework problem. Generally friend function, friend class is not asked in interviews and generally it becomes a slightly difficult topic to understand for some students. So that is why we are not covering it because from the point of view of interview, not many companies ask it.
But if you are interested in OOPS, then you can definitely go and read it once and learn it. So it will also make our understanding in OOPS. So I hope that our whole lecture today was one shot in this. We learnt a lot of different concepts, we learnt a lot of new things.
Whatever you found the best part, you can let me know that this was the best part and this was the time when we got to learn something new. So I think that thing as a teacher everyone likes. Along with this, all the MCQs based on this whole chapter, we have to go and solve them.
We have to make notes of all the things properly, remember the definitions, you can remember the examples, otherwise you can create your own examples. for interviews if you cover as much as we have covered so you are completely ready for OOPS interviews with these concepts only majority of the questions will be covered you should understand every concept well so I hope that in today's lecture we have learnt a lot of new things we have learnt a lot of good things which we will implement and all the best for your internship as well as placement interviews so that's it for today, see you in the next lecture till then keep learning and keep exploring