Learntofish's Blog

A blog about math, physics and computer science

Tutorial: OOP in C++ (Part 2 – Class and object)

Posted by Ed on October 6, 2012

This is part 2 of the C++ Object Oriented Programming tutorial. Last time we focused on using multiple files. Today we will have a look at classes and objects.

1. Definition of a class

Consider this example: Albert Einstein, Frank Sinatra, Marie Curie, what do they have in common? Obviously, they are persons. We say they are objects of the class “Person”. In general, a class describes its objects by two things:
1. Attributes (properties)
2. Methods (functions that can access attributes and change them)

The Person class above may have the attributes “name” and “age”. We will give it the method “talk()” which allows our objects to actually talk.

Let’s write the Person class in C++:
– Create a new project in Codelite and call it “personClass” by right-clicking on the orange “Tutorial” folder from last time. Then double click the “personClass” folder to set the project as active.
– Open the “main.cpp” file in the yellow “src” folder and replace the code by:

#include <iostream>
#include <string>
using namespace std;


// definition of class "Person"
class Person{

	// attributes	
	private:
		string name;
		int age;
   
	// methods
	public:
		Person(string myName, int myAge){
			name = myName;
			age = myAge;
		}

		void talk(){
			cout << "Hi! My name is " << name << " and I am " << age << " years old." << endl;
		}
};   // <--- Don't forget the semicolon here!


// main() function
int main(){

	Person p("Homer", 42);    // Create an object of the class "Person"
	p.talk();                 // Let the object talk
	
	return 0;
}

– In line 07-24 we defined our class “Person”.
– Line 10-12 contains the attributes (properties) that describe a “Person” object. The keyword “private” means that only methods (functions) can access the attributes.
– Line 15-23 contains the methods (functions). Notice the keyword “public” which means that we can apply the “dot” operator to our object. We will see further below what this means.
– Line 16-19 shows the so-called constructor. The constructor is just a special method with the following properties:
(i) It always has the same name as the class.
(ii) It has no return type.
(iii) It initializes, i.e. assigns initial values to our attributes.
– Line 21-23 shows the method “talk()”. It accesses the attributes to let the object talk.
– Line 24 is important: Don’t forget the semicolon to mark the end of the class.

– Line 28-34 shows the main() function. Line 28, 33 and 34 are always part of the main() function.
– In line 30 we create an object of the Person class. The name of the object is simply p, i.e. we write Person p.
Behind p we pass the name and age, in this case “Homer” is the name and 42 the age, i.e. we write Person p(“Homer”, 42).
– In line 31 we let the object p talk by applying the “dot” operator to it. We write p.talk().

Compile and run the program, and you should get the following output in the console:

Hi! My name is Homer and I am 42 years old.

2. Splitting the class
We will now split the class into declaration and implementation similar to last time:
Change the main.cpp file as follows:

#include <iostream>
#include <string>
using namespace std;


// definition of class "Person"
class Person{

	// attributes	
	private:
		string name;
		int age;
   
	// methods, now only with the function prototype (declaration)
	public:
		Person(string myName, int myAge);
		void talk();
		
};   // <--- Don't forget the semicolon here!



// main() function
int main(){

	Person p("Homer", 42);
	p.talk();
	
	return 0;
}


// methods implementation
// Notice the "Person::" in front of the function names
Person::Person(string myName, int myAge){
			name = myName;
			age = myAge;
}

void Person::talk(){
			cout << "Hi! My name is " << name << " and I am " << age << " years old." << endl;
}

– In line 07-19 we have the “Person” class. However, notice line 16 and 17. These lines only contain the function prototypes (declaration) without the implementation!
– The implementation is now in line 35-42. Notice how we have put “Person::” in front of the function names. This is necessary because otherwise C++ doesn’t know to which class the implementation belongs.

Compile and run the code, and you should still get the same output.

3. Using a header file
We will now use multiple files.
a) The definition of the “Person” class which contains only the declaration and no implementation is put into a header file (see last time). We will name the header file “person.h”.
b) The implementation is put into a file called “person.cpp”.
c) We include the header file in the main.cpp file.

The files should look like this:

a) person.h header file

#ifndef PERSON_H         // this is the so-called "include guard"
#define PERSON_H         

#include <string>
using namespace std;

// definition of class "Person"
class Person{

	// attributes	
	private:
		string name;
		int age;
   
	// methods, now only with the function prototype (declaration)
	public:
		Person(string myName, int myAge);
		void talk();
		
};   // <--- Don't forget the semicolon here!

#endif

– Line 01, 02 and 22 are part of the so-called “include guard”. When C++ includes this header file the first time the name PERSON_H is assigned to it.
If you try to include this header file a second time, which would result in an error, C++ checks if the name PERSON_H already exists. Since PERSON_H already exists from the first include, the header file is not included again which prevents an error.
– More on the include guard can be found here: learncpp

b) implementation file person.cpp

#include "person.h"   // This inserts the content of person.h here
                      // This is necessary since otherwise C++ does not know
					  // what Person:: below means.
#include <iostream>

// methods implementation
// Notice the "Person::" in front of the function names
Person::Person(string myName, int myAge){
			name = myName;
			age = myAge;
}

void Person::talk(){
			cout << "Hi! My name is " << name << " and I am " << age << " years old." << endl;
}

person.cpp contains the implementation of the functions. Notice that in line 01 we have to include the header file. This is necessary since otherwise C++ will complain that it does not know what “Person::” means.

3. main.cpp file

#include <iostream>
#include <string>
#include "person.h"  // This serves as sort of prototype
					 // Recall that the prototype is always above 
					 // the main() function.
using namespace std;


// main() function
int main(){

	Person p("Homer", 42);
	p.talk();
	
	return 0;
}

– In line 03 of the main.cpp file we have included the “person.h” header file. You can think of this as including a prototype of a function which always has be above the main() function.

Compile and run the program. You should still get the same output as before.

4. Exercise
a) Create another object: Person p2. The name of the person is “Marge” and the age is 38. Let her talk.
b) Try to recreate the “Person” class from scratch.

Solution:
Part a) Add the following code to the main() function:

Person p2("Marge", 38);
p2.talk();

Part b) See above.

5. References
1. C++ Lesson 10.0 – Multiple Files
This is the best video that explains the splitting of the class into multiple files.
2. C++ tutorial 60 – header files (part 1)
This is a nice tutorial by the thecplusplusguy.
3. cplusplus.com tutorial
My favorite tutorial on C++.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: