Classes
Objects on the heap and objects on the stack
File: maincpp
File: person.h
File: person.cpp
There are 2 different ways of creating objects in C++. One is on the stack and other on heap. The stack object is created with the statement: Person person1 ; After the execution of the above statement an object has been created on the stack. It's constructor has also been called and we are ready to start using the object. The other way is to dynamically allocate the memory for the object. personPtr = new Person() ; personPtr->print() ; This also creates an object but the object is created on the heap and then the constructor is called. If we have a pointer to int such as: int* ptr l Then we can access the value that the pointer points to by using the syntax: *ptr1 We can use similar notation to access a class methods and data using a pointer. (*personPtr).print() ; C++ gives us an alternate and easier way to do this. personPtr->print() ; We can use the "->" notation if the variable is a pointer. Remember if something is created on the heap then it must be deleted by the programmer . This is what happens in the line: delete personPtr ; The "delete" statement didn't have to be in this function. It could be in another function also. What happens if our program keeps running but we forgot to do "delete" on this particular object. There will be a memory leak in the program. Of course when the program ends then the memory will be released for the whole program. Include Guard Notice in the header file we have the lines: #ifndef PERSON_H #define PERSON_H #endifThese are preprocessing directives. Remember there are 2 steps in C++ compilation. At first the preprocessor goes through the ".cpp" file and processes it to produce another modified ".cpp" file that it compiles. Also an include statement normally copies the contents of the "include" file and pastes it in the ".cpp" file. Say we have a file "main.cpp" that uses the Person.h file.
Ex: main.cpp #include "person.h" #include "myutil.h" int main() { //Bunch of statements return ( 1) ; }
Now it turns out "myutil.h" is also using "person.h". Ex myutil.h #include "person.h" So if we look at our "main.cpp" we see that it includes "person.h" but by including "myutil.h" it will also include what's in "util.h" and that is "person.h" so the file "person.h" gets included twice. This will cause a compiler error as C++ does not allow duplicate declarations. To prevent duplicate header files we use the include guard. The "ifndef" means if the variable "PERSON_H" is not defined. The name "PERSON_H" can be anything but the convention is put the name of the header file with underscore and then "H" with the whole name being in capitol. For the first time we encounter include "person.h" we define the variable "PERSON_H" in the line: #define PERSON_H What the preprocessor does is it includes everything to the end "#endif" . Now let's say we encounter the header file again: #ifndef PERSON_H When the preprocessor encounters the above line it will check if the variable "PERSON_H" is defined and since it is the preprocessor will not enter the if conditions and will not include lines from the header file making sure that the file contents of "person.h" are not included more than once in a ".cpp" file. Remember the role of header files is only inside "cpp" files. During compilation we only give ".cpp" files to the "g++" command.
Exercise
Create 3 files named "vehicle.cpp" , "vehicle.h" and "main.cpp" . The vehicle class should have 3 data members ( that can be public ) weight of car, top speed, number of wheels and a method "print" that does not take any arguments and prints the 3 values. The "vehicle.cpp" contains the definition for the method "print()" while the "vehicle.h" contains the declaration. Place an include guard in the "vehicle.h" file. Create the file "main.cpp" that includes the "vehicle.h" and creates an object of type "vehicle". Assign some values for the data members and call the "print()" function.
Solution
File main.cpp
File vehicle.h
File vehicle.cpp