Object Oriented Programming in C++ ( Class-based programming )

” Object-oriented programming (OOP) is a programming paradigm that represents concepts as “objects” that have data fields (attributes that describe the object) and associated procedures known as methods. Objects, which are usually instances of classes, are used to interact with one another to design applications and computer programs. ” ( http://en.wikipedia.org/wiki/Object-oriented_programming ) .

I think this is the most relevant definition of OOPObject-oriented programming ).  In this statement there are same keywords that are very important :  objects , methods , instances , classes.

I will go straight into an example to illustrate what these keywords means :

OOP Simple Example I ( Construct a class )

#include

// Square CLASS

class Square
{
// private variables
const double mc_x;
const double mc_y;
const double mc_length;
public:
// public constructor
Square(const double ac_x, const double ac_y, const double ac_length);
// public destructor
~Square();

};

// Constructor implementation ( every private const member variable ,
// is equal with the correspondent const argument of the constructor )
Square::Square(const double ac_x, const double ac_y, const double ac_length) :
mc_x(ac_x),
mc_y(ac_y),
mc_length(ac_length)
{

}

Square::~Square()
{
// we don't have nothing to delete
// since we don't use pointers
}

int main()
{
// Square class instance
Square lv_Square(10, 10, 4);

return EXIT_SUCCESS;
}

In this example we have a Class declaration , the class name is Square and is defined with a simple constructor that only transfer the value from argument variables to member variables . We have a destructor, that is called in this case when the square Objectlv_Square ) is not longer available ( when the object is out of scope ,  that happens when main function  ends). If the  lv_Square was a pointer , then a manual delete should be present in order to call the destructor.
Into the main function we can see an instance of the Square class with 3 arguments ( 10 -> X , 10 -> Y , 4 -> Length).

1. Square  :  is a class that has a constructor and a destruct-or  and same constant member variables

2. Square lv_Square(10, 10, 4);  :  this is an instance of the Square  class

3. lv_Square  :  is an object that represents the Square class

We already use 3 keywords ( Class , Object and Instance) , there is only one keyword left that will be explained in the next example.

OOP Simple Example II ( Work with a class )

#include

// Square CLASS

class Square
{
// private variables
const double mc_x;
const double mc_y;
const double mc_length;
public:
// public constructor
Square(const double ac_x, const double ac_y, const double ac_length);
// public destructor
~Square();

const double mf_nGetPerimeter();
};

// Constructor implementation ( every private const member variable ,
// is equal with the correspondent const argument of the constructor )
Square::Square(const double ac_x, const double ac_y, const double ac_length) :
mc_x(ac_x) ,
mc_y(ac_y) ,
mc_length(ac_length)
{
std::cout << "Square Constructor" << std::endl;
}

Square::~Square()
{
// we don't have nothing to delete
// since we don't use pointers
std::cout << "Square Destructor" << std::endl;
}

const double Square::mf_nGetPerimeter()
{
return 4.0 * mc_length;
}

int main()
{
//*** First Demo *****
std::cout << "*** First Demo *****" << std::endl << std::endl;
{
// Square class instance
Square lv_Square(10, 10, 4);

std::cout << "Square Perimeter :  " << lv_Square.mf_nGetPerimeter() << std::endl  ;
}; // This when the Square destructor is called
std::cout << std::endl;

//*** Second Demo *****
std::cout << "*** Second Demo *****" << std::endl << std::endl;
{
// lv_Square is a pointer
Square* lv_Square = new Square(10, 10, 4);
std::cout << "Square Perimeter :  " << lv_Square->mf_nGetPerimeter() << std::endl;
}; // The destructor will not be called here , becase lv_Square is a pointer and we don't have a delete
std::cout << std::endl;

//*** Third Demo *****
std::cout << "*** Third Demo *****" << std::endl << std::endl;
{
// lv_Square is a pointer
Square* lv_Square = new Square(10, 10, 4);
std::cout << "Square Perimeter :  " << lv_Square->mf_nGetPerimeter() << std::endl;
delete lv_Square;
}; // In this case the destructor will be caled since a delete is present

std::cin.get();
return EXIT_SUCCESS;
}

class

First of all , you can see that in the “Second Demo” the object is not deleted , that is because it is a pointer and a pointer is deleted only when the delete is called . Let’s focus now on the other keyword that is methods . As you can see in this version of code I’ve added a method called mf_nGetPerimeter() that simply returns the perimeter of the Square object.

Now that all the keywords are clear let’s focus on a more advance example :

OOP Example I ( Inheritance )

#include

//***************
//****Person*****
//***************
class Person
{
public:
Person(const std::string& ma_szName, const int& ac_nAge );
~Person();

const std::string& mf_szGetName()
{
return mc_szName;
}

const int& mf_nGetAge()
{
return mc_nAge;
}

private:
const std::string mc_szName;
const int mc_nAge;
};

Person::Person(const std::string& ac_szName, const int& ac_nAge) :
mc_szName(ac_szName) ,
mc_nAge(ac_nAge)
{
std::cout << "***Person C-tor***" << std::endl;
}

Person::~Person()
{
std::cout << "***Person D-tor***" << std::endl;
}

//***************
//****Student****
//***************
class Student : public Person // Inheritance
{
public:
Student(const std::string& ac_szName, const int& ac_nAge , const std::string& ac_szUniversity);
~Student();

const std::string& mf_szGetUniversity()
{
return mc_szUniversity;
}

private:
const std::string mc_szUniversity;
};

Student::Student(const std::string& ac_szName, const int& ac_nAge, const std::string& ac_szUniversity) :
Person(ac_szName, ac_nAge) ,
mc_szUniversity(ac_szUniversity)
{
std::cout << "***Student C-tor***" << std::endl;
}

Student::~Student()
{
std::cout << "***Student D-tor***" << std::endl;
}

//***************
//****Teacher****
//***************
class Teacher : public Person // Inheritance
{
public:
Teacher(const std::string& ac_szName, const int& ac_nAge, const std::string& ac_szSubject);
~Teacher();

const std::string& mf_szGetSubject()
{
return mc_szSubject;
}

private:
const std::string mc_szSubject;
};

Teacher::Teacher(const std::string& ac_szName, const int& ac_nAge, const std::string& ac_szSubject) :
Person(ac_szName, ac_nAge) ,
mc_szSubject(ac_szSubject)
{
std::cout << "***Teacher C-tor***" << std::endl;
}

Teacher::~Teacher()
{
std::cout << "***Teacher D-tor***" << std::endl;
}

int main()
{
// First Demo
{
std::cout << "First Person" << std::endl;
Person lv_FirstPerson("Simon", 30);
std::cout << "First Person Name and Age : " << lv_FirstPerson.mf_szGetName().c_str() << " ; " <<  lv_FirstPerson.mf_nGetAge() << std::endl;
std::cout << std::endl;

std::cout << "First Teacher" << std::endl;
Teacher lv_FirstTeacher("James", 54, "Physics");
std::cout << "First teacher Name, Age and Subject : " << lv_FirstTeacher.mf_szGetName().c_str() << " ; " << lv_FirstTeacher.mf_nGetAge()
<< " ; " << lv_FirstTeacher.mf_szGetSubject().c_str() << std::endl;
std::cout << std::endl;

std::cout << "First Student" << std::endl;
Student lv_FirstStudent("Joe", 20, "MIT");
std::cout << "First student Name, Age and Univesity : " << lv_FirstStudent.mf_szGetName().c_str() << " ; " << lv_FirstStudent.mf_nGetAge()
<< " ; " << lv_FirstStudent.mf_szGetUniversity().c_str() << std::endl;
std::cout << std::endl;
};

std::cout << std::endl;
std::cout << std::endl;

// Second Demo
{
std::cout << "Second Teacher" << std::endl;
Person* lv_pSecondTeacher = new Teacher("Emma", 36 , "Chemistry"); // A teacher is a person too
std::cout << "Second Teacher:" << std::endl;
std::cout << "Name : " << lv_pSecondTeacher->mf_szGetName().c_str() << std::endl;
std::cout << "Age : " << lv_pSecondTeacher->mf_nGetAge() << std::endl;
// But because we construct a teacher with a pointer person we don't have the methods that are related with a teacher
// The same goes if we construct a student with a person pointer
delete lv_pSecondTeacher; // delete the lv_pSecondTeacher because it is a pointer and it will delete by itself
};

std::cin.get();

return 0;
}

Output:

class

Diagram:

class

I tried to comment the code , I think it will be easier to understand for those who are relay new in this , but of course if there are same questions, I will answer them as quick as I can .

You can see in this diagram that we have three classes : Person , Teacher and Student you can also deduce the base class and the derived classes , in this case the base class is Person and the derived classes are Teacher and Studentit can be also seen that we deal with a  public inheritance , and we can also see what methods each classes have.

For the Person class (base class) we have 2 member variables :  a string that represents the name of the person and an integer that represents the age of the person . Methods : for getting the age of the person and for getting the name of the same person .

For the Teacher class ( one of the derived classes ) we have one member variable : a string that represents the delivered subject. Methods : for getting the subject.

For the Student class ( the other derived classes ) we have one member variable : a string that represents the University were the student study. Methods : for getting the university.

Now that we know each object description , we have another thing that we should know : What is an inheritance ?  ” In object-oriented programming (OOP), inheritance is when an object or class is based on another object or class, using the same implementation; it is a mechanism for code reuse. The relationships of objects or classes through inheritance give rise to a hierarchy.” (http://en.wikipedia.org/wiki/Inheritance_%28object-oriented_programming%29)

Basically if we have an object derived from another object we can( must ) construct the derived object with the constructor of the base class , and on the derived object we have access to a all public or protected  member variables or methods . As you can see in my example  lv_FirstStudent is a Student object but I have access to all public methods inside the Person class , that is because Student class is derived from Person class.

Another thing that you will probably find interesting , is this implementations :

Person* lv_pSecondTeacher = new Teacher(“Emma”, 36 , “Chemistry”)

Well , we get back to the inheritance and because the Teacher class is derived from the Person class , we can construct on Teacher object with a Person pointer definition, but if we use this implementation we only have access at those methods that are linked with the base class , in this case we only have access at the methods described in the Person class , we can not use methods that are related with the Derived class. We will talk into a next article about much more things, I think for now this is enough and I am waiting for your questions and remarks , I hope this post it was useful for you :).

Author: Horațiu Condrea

My name is Horațiu Condrea, and I work as a Software Developer Manager at Siemens PLM Software. I hope that my experiments will prove to be useful for many of you guys/girls out there. Don’t forget to leave a comment whenever you run over a bug or something that is not working as it should be. For any kind of information contact me.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.