June 5, 2015 - coding cpp

Basic OOP with C++

Xavier Geerinck

@XavierGeerinck

This article is going to explain 1 example of an Object Oriented Program for C++.

We will create a small program that allows us to create figures, these being:

  • A circle
  • A rectangle
  • A square

We note that the square is a special rectangle.

Then on the end when we put this into our main method, then we will get the surface and the outline of the figures back.

int main() {
Circle circle(1); // Radius 1
cout << circle << endl; // Print: Surface: xxx Outline: xxx
Rectangle rectangle(2, 3); // Length 2, Width 3
cout << rectangle << endl; // Print: Surface: xxx Outline: xxx
Square square(4); // Side 4
cout << square << endl; // Print: Surface: xxx Outline: xxx
return 0;
}

Imports

The imports are also given, because the purpose of the exercise is to get to know the basics of Object Oriented Programming.

#include
#include
#include
#include
#include
using std::cout;
using std::string;
using std::endl;
using std::vector;
using std::acos;
using std::ostream;

Getting started

We will only create a main.cpp since we are not going to bother creating multiple files for this small program.

After we have written down our includes and the main that we were given above we can start writing, We see that we have 4 objects:

  • Figure : Base object, so this should be abstract
  • Rectangle : A figure, with a width and a length
  • Square : A rectangle, but instead of a width and a length just a side
  • Circle : A figure, with a radius

When we wrote down these 4 objects, we can clearly see that the Figure object is our most important object, so we start implementing this.

Note that the Figure object should be implemented abstract, with this we mean that we should not be able to create a Figure object that stands on it's own. (Simplified explanation, but easier to understand, for the full details I encourage you to go to Wikipedia ;) ).

Figure class

So we create a class called Figure and add the methods called get_surface and get_outline. These methods should be virtual (since we need to override them! and they should not be used otherwise) and have = 0 on the end (this makes it abstract).

And last but not least we need to create our method that will output the surface and the outline for every object that we send to cout. We do this here and not in the objects themselves because this is a generic method and we do not want to write this multiple times, to do this we just create the ostream& operator<<(ostream &os, const Figure &f) method and we make it a friend method! (friend means that we can acces the private and protected members of a class)

Implementation:

public:
virtual double get_surface() const = 0;
virtual double get_outline() const = 0;
friend ostream&amp; operator<<(ostream &amp;os, const Figure &amp;f) {
os << "Surface: " << f.get_surface() << endl;
os << "Outline: " << f.get_outline() << endl;
return os;
}
};

Rectangle class

After having created the Figure class we see that we need a Rectangle class, since the square inherits from the rectangle class.

The rectangle class is pretty straightforward, but we have to note that we need to inherit from our Figure class. We do this by appending : public Figure after our class declaration, this says that we will inherit from Figure.

Since we have inherited from Figure we will need to implement the get_surface and the get_outline methods in this class too, this is because the Figure class is abstract.

Implementation:

class Rectangle : public Figure {
public:
Rectangle(int length, int width) : m_length(length), m_width(width) {};
double get_surface() const { return m_length * m_width; }
double get_outline() const { return m_length * 2 + m_width * 2; }
private:
int m_length;
int m_width;
};

Square class

For our square class, we need to inherit from Rectangle, we do this again by appending the : public Rectangle line in our class header AND we define the rectangle properties by calling the constructor of our Rectangle by adding : Rectangle(side, side) after our constructor which will set the length and the width to our side.

Implementation:

class Square : public Rectangle {
public:
Square(int side) : Rectangle(side, side) {};
};

Circle class

For our last class, we do almost exactly the same as we did with the Rectangle class, only here we will use the M_PI constant that we have imported (see the imports) to calculate the surface and the outline.

Implementation:

class Circle : public Figure {
public:
Circle(int radius) : m_radius(radius) {};
double get_surface() const { return M_PI * m_radius * m_radius; }
double get_outline() const { return 2 * M_PI * m_radius; }
private:
int m_radius;
};

Running the Program

When we now run our program we will get the result that we wanted:

Surface: 3.14159
Outline: 6.28319
Surface: 6
Outline: 10
Surface: 16
Outline: 16

As an extension to this program, it would be nice that we could show which object we are printing, so a name attribute would be nice to have. Go ahead and implement this on your own :)

Full Code

#include
#include
#include
#include
#include
using std::cout;
using std::string;
using std::endl;
using std::vector;
using std::acos;
using std::ostream;
class Figure {
public:
explicit Figure() {};
virtual double get_surface() const = 0;
virtual double get_outline() const = 0;
friend ostream&amp; operator<<(ostream &amp;os, const Figure &amp;f) {
os << "Surface: " << f.get_surface() << endl;
os << "Outline: " << f.get_outline() << endl;
return os;
}
};
class Rectangle : public Figure {
public:
Rectangle(int length, int width) : Figure(), m_length(length), m_width(width) {};
double get_surface() const { return m_length * m_width; }
double get_outline() const { return m_length * 2 + m_width * 2; }
private:
int m_length;
int m_width;
};
class Square : public Rectangle {
public:
Square(int side) : Rectangle(side, side) {};
};
class Circle : public Figure {
public:
Circle(int radius) : Figure(), m_radius(radius) {};
double get_surface() const { return M_PI * m_radius * m_radius; }
double get_outline() const { return 2 * M_PI * m_radius; }
private:
int m_radius;
};
int main() {
Circle circle(1); // Radius 1
cout << circle << endl; // Print: Surface: xxx Outline: xxx
Rectangle rectangle(2, 3); // Length 2, Width 3
cout << rectangle << endl; // Print: Surface: xxx Outline: xxx
Square square(4); // Side 4
cout << square << endl; // Print: Surface: xxx Outline: xxx
return 0;
}

Xavier Geerinck © 2020

Twitter - LinkedIn