Skip to content

July 10, 2012

Quick Guide to Object Oriented Programming in C++ (Part 2)

by noise

This is a second part from a quick guide to Object Oriented Programming in C++ (aka OOP). We want this guide to be a very practical intro to Object Oriented Programming in C++.

In this tutorial we will write some examples that describe make use of encapsulation, inheritance. and polymorphism

1. Encapsulation

Encapsulation is the process of hiding implementation informations of a class or function so that only needed information will be available to the user of the class. This way we protect the the class/library against directly accessing/modifying values of some variables of the class for example that should have some values only. For example if we have a variable in a class that keep Score and we do not want the minimum and maximum score to be in a range we can hide that variable and only allow Setters and Getters functions to access it. A Setter function is a member function of that class that we will define, it’s a function that have access to that variable and set the value for that variable. We cannot access that variable directly but that member function can. And that Setter function (we call it Setter function because it sets a value for that variable) will know to set score within a range and will take care of wrong values added by user of the class.

So to make use of encapsulation we will use public, private and protected identifiers.

1.1 Public identifiers

All function members and variables defined after public: identifier are defined to be public so they can be access from anybody, that means they can be accessed from outside and also from other classes that inherit the main class. We did not talked about inheritance yet but we will do, later in this tutorial.

A quick example of defining public variables or/and function members within a class is presented next.

// Score.h, our header file for Score class
#ifndef SCORE_H
#define SCORE_H
#include <string>
 
using namespace std;
 
class Score {
    public:
        // class constructor
        Score();     
        // class destructor
        ~Score();
 
        void SetPlayerName(char * playerName);
        string GetPlayerName();
 
        void SetScore(int sc);
        int GetScore();
 
    private:
        char * playerName;
        char * playerName2;
        int score;
};
#endif

If we look in previous example after the public: tag we will see that all function members defined until private: tag are defined as public so all are accessible to everybody.

1.2 Private identifiers

Variable defined after private: tag are of course private which means class variables and function members defined after this tag can be accessed only by class’s objects.

If you look at previous example you will see that playerName variable is defined as private which means only function members of the class or of the objects that inherit that class will be allowed to access that variable.

1.3 Protected indentifiers

As we mentioned in first tutorial, variables and function members defined after protected: identifier can be accessed by class’s objects and by objects derived from the parent class.

You will see an example of protected variables and function members later in this tutorial.

1.4 How to use encapsulation (Example 1)

As we said earlier to make use of encapsulation we will use setter and getter member functions.

Let’s write a simple example of a PhoneBook app that will store names, and age into a class. We will change the name or the phone using a setter member function that we will define and we will use a getter member function to
display the name. Of course a PhoneBook app should contains other fields like phone, email, address but for the sake of simplicity we will only define name and age fields. If you want to complete the app and add the fields we’ve mentioned previously feel free to do it, it’s similar to the fields we’ve implemented.

So our PhoneBook app will have the following files: MyPhoneBook.h (which is the header file for our class), MyPhoneBook.cpp (which is the implementation file for our class) and main.cc which is our main source code that make use of the class.

// MyPhoneBook.h - our header file for MyPhoneBook class
// which is our main class
#ifndef MYPHONEBOOK_H
#define	MYPHONEBOOK_H
 
#include <string>
#include <iostream>
 
using namespace std;
 
class MyPhoneBook {
public:
    MyPhoneBook();
    MyPhoneBook(const MyPhoneBook& orig);
    virtual ~MyPhoneBook();
 
    void SetName(string aName);
    string GetName();
 
    void SetAge(int personAge);
    int GetAge();
 
private:
    string personName;
    int age;
};
#endif

The implementation file for our class follows (MyPhoneBook.cpp):

// MyPhoneBook.cpp - implementation file for MyPhoneBook class
#include "MyPhoneBook.h"
 
MyPhoneBook::MyPhoneBook() {
}
 
MyPhoneBook::MyPhoneBook(const MyPhoneBook& orig) {
}
 
MyPhoneBook::~MyPhoneBook() {
}
 
void MyPhoneBook::SetName(string aName) {
    personName = aName;
}
 
string MyPhoneBook::GetName() {
    return personName;
}
 
void MyPhoneBook::SetAge(int personAge) {
    if (age < 0 || age < 120)
        age = personAge;
    else {
        cout << "Error, age out of bound";
        exit (1);
    }   
}
 
int MyPhoneBook::GetAge() {
    return age;
}

And finally our main file which contains main() function and make use of our class (main.cpp):

// main.cpp
#include <cstdlib>
#include <iostream>
#include "MyPhoneBook.h"
 
using namespace std;
 
int main(int argc, char** argv) {
 
    MyPhoneBook name1, name2;
 
    name1.SetName("Jimmy");
    name1.SetAge(20);
 
    name2.SetName("Mary");
    name2.SetAge(23);
 
    cout << "name for name1 = " << name1.GetName() << endl;
    cout << "age for name1 = " << name1.GetAge() << endl;
 
    cout << "name for name2 = " << name2.GetName() << endl;
    cout << "age for name2 = " << name2.GetAge() << endl;
    return 0;
}

2. Inheritance

When working with objects we can define a relation between objects such us inheritance so an object could be able to inherit all member functions from the parent object. And yes, if the object inherit from a parent object we we will
call that object child.

When we design programs that use inheritance we will define first the main class which will have general characteristics and then the child will inherit those characteristics and will add other specific characteristics to it’s objects

2.1 Let’s see some code for Inheritance (Example 2)

Let’s define for example a class called MyFigure which will have a variable figureName, a setter and a getter for that variable and then we will define a subclass called MyShape which will inherit everything from MyFigure class and will also have other member functions and variables.

So MyFigure is our base class (parent class) and MyShape is our derived class (child class). We will use a variable called figureName defined in our parent class (MyFigure) that will be inherit into MyShape class. For the variable figureName to be accessible in our child class we must define it protected in our parent class.

Then in our child class we will only define edges variable which will store number of edges of the figure.

So files are as follows: MyFigure.h (our class header definition file for MyFigure and MyShape classes), MyFigure.cpp (our class implementation file for MyFigure and MyShape classes) and our
main file (main.cpp) which contains our main() function of the program.

MyFigure.h file:

// MyFigure.h file
#ifndef MYFIGURE_H
#define	MYFIGURE_H
 
#include <string>
 
using namespace std;
 
class MyFigure {
public:
    MyFigure();
    MyFigure(const MyFigure& orig);
    virtual ~MyFigure();
 
    void SetFigureName(string fName);
    string GetFigureName();
 
protected:
    string figureName;
 
};
 
class MyShape : public MyFigure {
public:
    MyShape();
    MyShape(const MyShape& orig);
    virtual ~MyShape();
 
    void SetShapeEdges(int noEdges);
    int GetShapeEdges();
 
private:
    string shapeName;
    int edges;
};
 
#endif	/* MYFIGURE_H */

MyFigure.cpp file:

#include "MyFigure.h"
 
MyFigure::MyFigure() {
}
 
MyFigure::MyFigure(const MyFigure& orig) {
}
 
MyFigure::~MyFigure() {
}
 
void MyFigure::SetFigureName(string fName) {
    figureName = fName;
}
 
string MyFigure::GetFigureName() {
    return figureName;
}
 
 
MyShape::MyShape() : MyFigure() {
 
}
 
MyShape::~MyShape() {
}
 
void MyShape::SetShapeEdges(int noEdges) {
    edges = noEdges;
}
 
int MyShape::GetShapeEdges() {
    return edges;
}

And finally our main file: main.cpp file:

#include <cstdlib>
#include <iostream>
 
 
#include "MyFigure.h"
 
using namespace std;
 
 
int main(int argc, char** argv) {
 
    MyShape aShape, bShape;
 
    aShape.SetFigureName("triangle");
    aShape.SetShapeEdges(3);
 
    bShape.SetFigureName("rectangle");
    bShape.SetShapeEdges(4);
 
    cout << "Figure: aShape = "<< aShape.GetFigureName() << endl;
    cout << "Shape edges = "<< aShape.GetShapeEdges() << endl << endl;
 
    cout << "Figure: bShape = "<< bShape.GetFigureName() << endl;
    cout << "Shape edges = "<< bShape.GetShapeEdges() << endl;
 
    return 0;
}

You will make use of SetFigureName() member function from our parent class which is inherited into our child class (and also figureName is inherited because it’s defined as protected: (being defined as such will
make use of encapsulation too, because of course we can define figureName as public but in that case we will lose encapsulation).

3. Polymorphism

Sometimes we have multiple derived objects of different types and we want to apply the same member function to all of them (but note that those objects are of different types). That member function will be defined in parent class and will be redefined in every child class to work for that specific object.

3.1 Using polimorphism (Example 3)

Let’s define a parent class called MyBasicShapes then let’s define two child classes: MyTriangle and MySquare. Then we will redefine our myArea() method from parent in every child object so that myArea()method will compute area of the triangle and of the square depending on the object type (so for MyTriangle objects we will compute aria for the triangle and for MySquare object we will compute aria of the square.

So our files are MyBasicShapes.h file, which will define MyBasicShapes class and it’s children classes MyTriangle and MySquare:

#ifndef MYBASICSHAPES_H
#define	MYBASICSHAPES_H
 
class MyBasicShapes {
public:
    MyBasicShapes();
    MyBasicShapes(const MyBasicShapes& orig);
    virtual ~MyBasicShapes();
 
    virtual int ComputeArea() = 0;
    int GetArea();
 
protected:
    int area;
};
 
 
class MyTriangle : MyBasicShapes {
public:
    void SetTriangleValues(int b, int h);
    int ComputeArea();
 
private:
    int base, height;
 
};
 
 
class MySquare : MyBasicShapes {
public:
    void SetSquareSide(int s);
    int ComputeArea();
 
private:
    int side;
 
};
 
#endif	/* MYBASICSHAPES_H */

Next is MyBasicShapes.cpp file, which will implement member functions for parent class MyBasicShapes and it’s children classes MyTriangle, MySquare:

#include "MyBasicShapes.h"
 
MyBasicShapes::MyBasicShapes() {
}
 
MyBasicShapes::MyBasicShapes(const MyBasicShapes& orig) {
}
 
MyBasicShapes::~MyBasicShapes() {
}
 
 
void MyTriangle::SetTriangleValues(int b, int h) {
    base = b; height = h;
}
 
int MyTriangle::ComputeArea() {
    return base*height/2;
}
 
 
 
void MySquare::SetSquareSide(int s) {
    side = s;
}
 
int MySquare::ComputeArea() {
    return side*side;
}

Our main file which will make use of the classes is main.cpp:

#include <cstdlib>
#include <iostream>
 
using namespace std;
 
#include "MyBasicShapes.h"
 
using namespace std;
 
int main(int argc, char** argv) {
 
    MyTriangle aTriangle;
    MySquare  aSquare;
 
    aTriangle.SetTriangleValues(5,4);
    cout << "Aria of our triangle is = " << aTriangle.ComputeArea() << endl;
 
    aSquare.SetSquareSide(3);
    cout << "Aria of our square is = " << aSquare.ComputeArea() << endl;
 
    return 0;
}

Note that our member function that is defined on our parent class ( ComputeArea() ) is only defined but is not implemented. Also note that this member function in our parent is =0 which makes it virtual pure function.More on that topic later.

This concludes our second quick tutorial on Object Oriented Programming in C++.

Read more from C and C++ Tutorials

Leave a Reply

required
required

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments