Showing posts with label Classes. Show all posts
Showing posts with label Classes. Show all posts

Bank Account System with Object-Oriented Programming in C++

In this tutorial, we will use all our knowledge of Object-Oriented Programming in C++, and create a real example of application, a bank account.

How to make a Bank Account System
Exercise: Bank Account

Create a system in which a user bank account is created, where he can check his balance, deposit and withdraw money, use object-oriented knowledge.

Your system should start by displaying a menu with these options, and allow the user to perform these operations as many times as he wants, and decide when to close the system.


The class: Client.h

The customer's balance will be stored in the cash variable. It is initialized with a value of 0, in the constructor function, that is, the customer obviously starts with 0 of money.

We have the menu() function, which will display the options menu, that is, the screen of the ATM of the banking system. It invokes the action() function, which will call each specific operation.

The first operation is checkBalance(), which will check the balance, the account balance.

Then there is the depositCash() function, which is used to add money to your account.

Finally, the withdraw() function, to withdraw money.

Our class looks like this:

#ifndef CLIENT_H
#define CLIENT_H


class Client
{
    public:
        Client();
        void menu();
        void action(int);
        void checkBalance();
        void depositCash();
        void withdraw();

    private:
        double cash;
};

#endif // CLIENT_H

Source: Client.cpp

Everything will start where you should start, with the Client() constructor function.

It simply clears your money, as it is as if your account was created the moment you instantiated the object.

The menu() function will be displaying a menu of options for the user, and asking him to enter a value. This value is stored in the op variable and sent to the action() function, this is done within a do while loop, which will only end if you type 0. In other words, you only exit the menu, if you type 0 to exit.

The action() will take an action, evaluating the op value received from the menu(). This is done in a switch conditional test.

If it is 0, it says that the system is shutting down.

If it is 1, invoke the checkBalance() function, which will simply display the cash variable. Nothing more.

At depositCash (), we ask the user for a value. But we have to test whether this value is positive, because obviously there is no way to deposit a negative value. This test is done on an IF ELSE. If the value is positive, we simply add it to the cash and display the user's balance.

In the withdraw() function, we ask for the amount the user wants to withdraw. Before removing this value from the cash variable, we need to assess whether it is less than cash. After all, you can only withdraw something below, or at most equal to your balance. This test is done with an IF ELSE as well.

Here's how the code looks:

#include "Client.h"
#include <iostream>
using namespace std;

Client::Client()
{
    cash = 0;
    menu();
}

void Client::menu()
{
    int op=0;

    do{
        cout<<"0. Exit"<<endl;
        cout<<"1. Check balance"<<endl;
        cout<<"2. Deposit money"<<endl;
        cout<<"3. Withdraw money"<<endl;
        cin >> op;

        action(op);

    }while(op);
}

void Client::action(int op)
{
    switch(op)
    {
        case 0:
                cout << "Shutting down system."<<endl;
                break;
        case 1:
                checkBalance();
                break;

        case 2:
                depositCash();
                break;

        case 3:
                withdraw();
                break;

        default:
                cout << "Invalid option"<<endl;
    }

}

void Client::checkBalance()
{
    cout<<"\nYour balance is: $" << cash <<endl;
}

void Client::depositCash()
{
    double val;

    cout<< "Value to deposit: ";
    cin >> val;

    if(val>0){
        cash += val;
        checkBalance();
    }
    else
        cout<<"Invalid value, try again"<<endl;

}

void Client::withdraw()
{
    double val;

    cout<< "Value to withdraw: ";
    cin >> val;

    if(val<=cash){
        cash -= val;
        checkBalance();
    }
    else
        cout<<"Insufficient funds"<<endl;
}

main.cpp

Our main will simply instantiate an object. Automatically it activates the constructor function, and everything starts to happen:

#include "Client.h"

int main()
{
    Client c;
    return 0;
}

See how our main() is simple, clean and to the point.


Hacker challenge

There is a way to hack this system. To add money to your account in a 'hacker' way. Can you find out how it is? Type in the comments.

Array of objects in C++

In this tutorial from our C++ e-book, we will learn how to create an array of objects, as well as how to manipulate them.

Creating an array with Objects in C++

In the past tutorial, we created a class that averaged two or three grades for students. We will do something similar in this tutorial.

Let's create the Student class, and initially it gets two grades. The constructor function correctly sets variables, and has a function called getAverage() that returns the average of the two grades:

#include <iostream>
using namespace std;
class Student
{
    private:
        double grade1, grade2;

    public:
        Student();
        Student(double, double);
        double getAverage();
};

Student::Student()
{
    grade1 = 0;
    grade2 = 0;
}
double Student::getAverage() { return (grade1+grade2)/2; } int main() { Student NeilPeart(10, 8); cout<<NeilPeart.getAverage()<<endl; return 0; }

Note that we created only one object, the student Neil Peart. But which school has only one student? There are thousands, but let's take it easy. We will now work with 5 students. We could do:

  • Student alu1, alu2, alu3, alu4, alu5;

But, what if it was a real project, with a thousand students? Would you do it up to the alu1000?
Of course not, right, buddy!

You studied by Progressive C++, you are a smart person and you will soon remember our beloved and beautiful arrays, to work with many variables at the same time.

To declare 5 integers, we do:

  • int num[5];

To declare 5 chars, we do:

  • char letter[5];

So guess what we do to create 5 objects of the Student class? That's right:

  • Student alu[5];

Array of Objects

Run the code to the code below:

#include <iostream>
using namespace std;

class Student
{
    private:
        double grade1, grade2;

    public:
        Student();
        Student(double, double);
        double getAverage();
};

Student::Student()
{
    grade1 = 0;
    grade2 = 0;
}

Student::Student(double g1, double g2)
{
    grade1 = g1;
    grade2 = g2;
}

double Student::getAverage()
{
    return (grade1+grade2)/2;
}


int main()
{
    Student alu[5];
    cout<<alu[0].getAverage()<<endl;

    return 0;
}

The result will be 0, as we don't initialize the array objects.

How to Initialize Objects from an Array

We could initialize the objects one by one, after declaring:

    Student alu[5];
    alu[0] = Student(10,9);
    alu[1] = Student(10,8);
    alu[2] = Student(10,7);
    alu[3] = Student(10,6);
    alu[4] = Student(10,5);

Or we could just initialize everything when instantiating objects:
    Student alu[5] = { Student(10,9),
                       Student(10,8),
                       Student(10,7),
                       Student(10,6),
                       Student(10,5) };
Or even directly:
    Student alu[5] = { {10,9},
                       {10,8},
                       {10,7},
                       {10,6},
                       {10,5} };
If you have other constructor functions (that receive one grade or 3, for example), you can also place them directly in the code, C++ will know how to call the correct constructor. And if you don't provide any information about any element of the array, C++ will invoke the default constructor (it's always good to have one in the class).

Accessing members of the Object Array

Ok, we have already declared and initialized several objects at once, now you need to learn how to access their members.

When we had an object named 'name', we accessed its members using a dot:
  • name.var
  • name.func()

Here's the same thing, but the variable is an array element:
  • arr[0].grade
  • arr[1].getAverage();
That is, the same thing, just use the cute array and the dot, followed by the member of the class / object.
The following program creates 5 objects, initializes with the students' grade and displays their averages with the getAverage() function:
#include <iostream>
using namespace std;

class Student
{
    private:
        double grade1, grade2;

    public:
        Student();
        Student(double, double);
        double getAverage();
};

Student::Student()
{
    grade1 = 0;
    grade2 = 0;
}

Student::Student(double g1, double g2)
{
    grade1 = g1;
    grade2 = g2;
}

double Student::getAverage()
{
    return (grade1+grade2)/2;
}


int main()
{
    Student alu[5] = { {10,9},
                       {10,8},
                       {10,6},
                       {10,5} };


    cout<<alu[0].getAverage()<<endl;
    cout<<alu[1].getAverage()<<endl;
    cout<<alu[2].getAverage()<<endl;
    cout<<alu[3].getAverage()<<endl;
    cout<<alu[4].getAverage()<<endl;

    return 0;
}
Note that we only initialized the first four students, so the fifth one was initialized by the default constructor. What was the average of the fifth student (alu[4])?

Now do another test: create a class, which only has the default constructor, displaying a message on the screen. Create an array of size 10, of these objects. What happens?

Constructor function overloading in C++

In this tutorial from our Progressive C++ course, we will learn about overloading the constructor functions.

Overload constructors in C++


Many constructors functions

You were hired by a university to create a system to help teachers, especially to work with students' grades.

As you took the Progressive C++ course, you will create a fantastic system, with several classes and objects, hardcore.
But let's take it easy.

Let's create a math class, called Math. For simplicity, she'll do just one operation: average two grades, one student, that's all.

The constructor function will tell the student's average right away.

See how our code looks:

#include <iostream>
using namespace std;

class Math
{
    public:
        Math(double, double);
};


Math::Math(double g1, double g2)
{
    cout<<"Average: "<<(g1+g2)/2<<endl;
}


int main()
{
    Math BruceDickinson(10, 8);

    return 0;
}

The result was 9 right, all nice and cool, and student Bruce Dickinson got a great average.

And speaking of market experience, it is SOOOO common for customers to be asking for changes, new features, etc. Get used to it, it is always requests and complaints.

In that case, the university now wants you to average 3 grades.

Time, it's very simple, just add one more parameter to the list of the constructor function, create the object with the 3 notes and send a bullet, that's it, our code looks like this:

#include <iostream>
using namespace std;

class Math
{
    public:
        Math(double, double, double);
};


Math::Math(double g1, double g2, double g3)
{
    cout<<"Average: "<<(g1+g2+g3)/3<<endl;
}


int main()
{
    Math NeilPeart(10, 9, 10);

    return 0;
}

Everything was fine and Neil Peart had an almost perfect average.

But then your university get in contact and says: look, there are students who will make two disciplines and students who will make three, that is, their system has to calculate the average in both cases.

And now? How will the constructor guess? One hour calculates the average by dividing by 2 and in the other example he divided by 3 because he had one more variable.

Create a class for each case? Of course not, as this is a complication.

Programming was made to make the world easier! This is where builder overloading comes in.


Constructors overloading in C++

C++ has a card up its sleeve: it allows you to create as many constructors as you want. That's right, functions with the same name.
But one thing has to be different: the list of parameters.

Example of a list of different parameters:

  • Math (double, double)
  • Math (double, int)
  • Math (int, double)
  • Math (double, double, double, float, char, int)
  • ...

So, in our example of averages, just create two constructor functions, one that receives two grades and the other that receives three grades:

#include <iostream>
using namespace std;

class Math
{
    public:
        Math(double, double);
        Math(double, double, double);
};

Math::Math(double g1, double g2)
{
    cout<<"Average: "<<(g1+g2)/2<<endl;
}

Math::Math(double g1, double g2, double g3)
{
    cout<<"Average: "<<(g1+g2+g3)/3<<endl;
}


int main()
{
    Math BruceDickinson(10, 8);
    Math NeilPeart(10, 9, 10);

    return 0;
}

See how smart C++ is. When you created the BruceDickinson object, you only passed two arguments, and the object invoked the constructor function that only works with two numbers.

When he created the ana object, he called the other constructor function, the one that works with three values.

That is, C++ calls the correct constructor!
This is the constructor overloading.

Now if you have two constructors with the same parameter list, then there is no way for C++ to guess what function you are trying to invoke, okay?

We will learn a little more about overload when we study a super special class, the string, which does crazy things and wonders with overloading.

Constructors Functions in C++ - Object Oriented

In this tutorial, we will learn about a special type of function, the Constructor function, which plays a very important role in object orientation.

The C++ Constructor function

There is a very important function and used in object oriented, it is the construction function.
And it has some unique and special features.

The first is that the name is the same as the class name. That is, if your class is called "MyClass", the constructor function must be called "MyClass()", mandatorily, ok?

Another characteristic of it is that, as soon as we instantiate an object, the constructor function is always automatically invoked!

Finally, one last characteristic, it does not return any value! Do not write void, int, doublet etc., anything in your header and implementation.

Let's see a test of a working construction function? Let's create the "MyClass" class that has only one member, the "MyClass()" function, which will simply display a message, it looks like this:

#include <iostream>
using namespace std;

class MyClass
{
    public:
        MyClass();
};

MyClass::MyClass()
{
    cout << "Progressive C++ Course"<<endl;
}

int main()
{
    MyClass c;

    return 0;
}

Prontinho! Apenas criamos o objeto 'c' e veja o que apareceu na tela:

Constructor functions



Construction function: What is it for?

Ok, we've already seen how to do it, how it works and the result ... but what is it for? Just to show some silly messages on the screen?
Of course not, young man!

As the name says, it serves to 'construct' things, in this case, it builds things automatically. When we create an object, it is interesting that it already does some internal operations immediately, without having to always do everything manually.

This type of constructor, we call it default, because it doesn't take any arguments. However, the most common and useful way to use a constructor function is with a list of parameters, which are information that comes from the outside into the object, and will play an important role inside.


Constructor function: How to use?

For example, let's look at our Rect class, which created rectangles. Remember that we always had to use the setter functions to define the length and width values. How about if the builder did this automatically?

See how it looks:

#include <iostream>
using namespace std;

class Rect
{
    private:
        double length, width;

    public:
        Rect(double, double);
        double getArea();
        double getPerimeter();
};

Rect::Rect(double l, double w)
{
    length = l;
    width = w;
}
double Rect::getArea()
{
    return length * width;
}
double Rect::getPerimeter()
{
    return 2*(length+width);
}

int main()
{
    double len, wid;

    cout<<"Length: ";
    cin >> len;

    cout<<"Width: ";
    cin >> wid;

    Rect r(len, wid);

    cout<<"Area: " << r.getArea() << endl;
    cout<<"Perimeter: " << r.getPerimeter() << endl;

    return 0;
}

Note that in the header of the constructor, we have already specified that it will receive two variables of type double.

In the implementation, we call these variables 'l' and 'w', which will be provided later by the user. And what does our constructor function do? It will set the correct values for 'length' and 'width'.

In main, we ask for the length and width values, and then simply instantiate an object of type Rect, named 'r'. Notice now that in it we send two arguments, which are the two arguments that the constructor function will use!

Ready, internally, inside the object, the constructor has already done everything and the functions getArea() and getPerimeter() can now be used.

A little more about the Constructor Function

Another curiosity about constructors is that they ALWAYS exist! Even if you don't define any, C++ goes there and creates one, empty, that does nothing.

When you do:

  • MyClass c;

It will automatically invoke the constructor, but you don't see anything happening, as you haven't defined any constructors.

Another trick you may need and use, is through pointers, declaring a pointer to an object:

  • MyClass * ptrClass;

When doing this, the constructor method will not be executed, since an object was not created, only a pointer to an object.

Now if you do this next:

  • ptrClass = new MyClass;

Then, the object was instantiated and allocated in memory, and the constructor will be summarily executed.

How to create a project with Classes and Objects in C++: Headers and Implementations

In this tutorial from our C++ e-book, we will learn how to organize our classes and function implementations, creating a very professional project.


How to create a C++ project

Open your Code :: Blocks (or any other IDE you are using).
Click File, then New and choose Project.
Choose Console application and check the C ++ option.
Give your project a name, choose the folder you want to save and click Finish,

It will look like this:


How to create a C++ project
Note that the file 'main.cpp' already came, we will use it.
Now, click on that white file up there, saying 'New file', and click on Class. Name this class as 'Calc' as we are going to create a calculator.

Now see how cool:

He created two files: Calc.h and Calc.cpp

Implementing a Class in a C++ Project: .h

Okay, come on, first let's work on the Calc.h file, it's called a header.
Let's go to the outline of our class.

It will have two numbers: num1 and num2, obviously private.
It will have functions of sum, subtraction (sub), multiplication (prod) and division (div), all public and const (they will not be able to change the variables).

Only the setNum1 and setNum2 functions will be able to change the variables.
And ready, our Calc.h class header looks like this:
#ifndef CALC_H
#define CALC_H


class Calc
{
    private:
        double num1, num2;

    public
        double sum() const;
        double sub() const;
        double prod() const;
        double div() const;
        void setNum1(double);
        void setNum2(double);
};

#endif // CALC_H
See that there are some #ifndef, #define, #endif ... do not touch them, they are super important, leave them there and then we explain their meanings.

Implementing Functions of a Project Class: .cpp

It is in this file that we will implement the functions of our Calc.h class

Note that at the very beginning, there is a "#include Calc.h", so this .cpp file is directly related to the .h file, do you understand the magic of it?

Note that there is no 'cout', if it did, we would have to include 'include <iostream>:

In this file, we will implement all the getters and setters functions that were previously presented in the class header. The .cpp file looks like this:
#include "Calc.h"

double Calc::getSum() const
{
    return num1+num2;
}

double Calc::getSub() const
{
    return num1-num2;
}
double Calc::getProd() const
{
    return num1*num2;
}
double Calc::getDiv() const
{
    return num1/num2;
}
void Calc::setNum1(double n1)
{
    num1=n1;
}
void Calc::setNum2(double n2)
{
    num2=n2;
}

Running our C++ project: main.cpp

Now, in main.cpp, the only thing you have to do is to include :#include "Calc.h" up there in the file, and that's it, see how the main went:

#include <iostream>
#include "Calc.h"

using namespace std;

int main()
{
    Calc c;
    double num;

    cout << "First number: ";
    cin >> num;
    c.setNum1(num);

    cout << "Second number: ";
    cin >> num;
    c.setNum2(num);

    cout << "\nResults: "<<endl;
    cout << "Sum: " << c.getSum()<<endl;
    cout << "Substraction: " << c.getSub()<<endl;
    cout << "Product: " << c.getProd()<<endl;
    cout << "Division: " << c.getDiv()<<endl;

}
Now imagine for a moment if we had declared this class and the implementations of the functions all in main.cpp, the mess it would be and the gigantic code.

This way we did, separating by headers (.h) and function implementations (.cpp), everything was more cute, organized and professional, that's how they do it and use it in professional software.

Get used to doing your projects with this organization, okay?

Dynamic allocation of objects with pointers: The new and delete operators

In this tutorial of our Object Orientation Course in C++, we will learn how to use pointers with objects, and see a new way to allocate memory.


Object Pointers

Initially, we will create a class, called Student, which will have two variables (math and english), which will store the student's grades. There will also be a get and set, and a getAverage() call to calculate the average for each student.

Our class, all complete and cute looks like this:

class Student
{
    private:
        double math, english;

    public:
        double getAverage() const;
        void setMath(double);
        void setEnglish(double);
        double getMath() const;
        double getEnglish() const;
};

double Student::getAverage() const
{
    return (getMath() + getEnglish())/2;
}

void Student::setMath(double m)
{
    math = m;
}
void Student::setEnglish(double e)
{
    english = e;
}
double Student::getMath() const
{
    return math;
}
double Student::getEnglish() const
{
    return english;
}

We will now declare a pointer named 'ptr' of type Student:

  • Student *ptrStudent

Now let's actually declare an object of the Student class:

  • Student s1;

We can associate the pointer with the object as follows:

  • ptrStudent = &s1

(don't forget &, remember that pointers store memory addresses, and by placing & before a variable, it gives the address of that variable)


Working with Pointers with Classes and Objects: ->

As we are already studying pointers, we saw that they can work wonders.
For example, in the previous example, for the pointer to access the elements of an object, we must use the operator ->

Let's define two grades for a student:
  • ptrStudent-> setMath (8);
  • ptrStudent-> setEnglish (10);

And to know the average, using a pointer, just do:
  • ptrStudent-> getAverage()

Our complete code is:
#include <iostream>
using namespace std;

class Student
{
    private:
        double math, english;

    public:
        double getAverage() const;
        void setMath(double);
        void setEnglish(double);
        double getMath() const;
        double getEnglish() const;
};

double Student::getAverage() const
{
    return (getMath() + getEnglish())/2;
}

void Student::setMath(double m)
{
    math = m;
}
void Student::setEnglish(double e)
{
    english = e;
}
double Student::getMath() const
{
    return math;
}
double Student::getEnglish() const
{
    return english;
}

int main()
{
    Student *ptrStudent;
    Student s1;

    ptrStudent = &s1;
    
    ptrStudent->setMath(8);
    ptrStudent->setEnglish(10);

    cout << ptrStudent->getAverage()<<endl;

    return 0;
}
Note that we used only one student, we could have created a thousand students and make the pointer point to each one of these students, and the code would always be the same, for example:
Student s1, s2, s3, s4;

Do: ptrStudent = &s1
Then: ptrStudent = &s2
Then: ptrStudent = &s3
Then ptrStudent = &s4

And ready, then just use usr
ptrStudent-> setMath();
ptrStudent-> setEnglish();
ptrStudent-> getAverage()

This avoids writing code for nothing.

Allocating space for objects: new operator

There is a new way to instantiate objects, it is from the new operator.
First you declare your pointer:
  • MyClass *ptr;
At this point, do we have a pointer to point to an object? What object is that? Let's create it now, as follows:
  • ptr = new MyClass

Deleting objects - delete

When we create an object, via normal instantiation, it will always exist and occupy a space in memory. One of the advantages of making dynamic memory allocation, through new, is that we can destroy this pointer, destroying this object and freeing space in memory, for this, just use the delete operator:
  • delete ptr;

And ready, we have a free space on the machine. This may seem silly now, but when you create super complex systems that require maximum efficiency and the least possible use of memory (such as programming a watch or microwave, which has little memory), it is a very important technique.

See the code below, just with a pointer, we fill the grade of two students and calculate their average, and all this just as an object / pointer of the Student class. See how the code looks:

#include <iostream>
using namespace std;

class Student
{
    private:
        double math, english;

    public:
        double getAverage() const;
        void setMath(double);
        void setEnglish(double);
        double getMath() const;
        double getEnglish() const;
};

double Student::getAverage() const
{
    return (getMath() + getEnglish())/2;
}

void Student::setMath(double m)
{
    math = m;
}
void Student::setEnglish(double e)
{
    english = e;
}
double Student::getMath() const
{
    return math;
}
double Student::getEnglish() const
{
    return english;
}

int main()
{
    Student *ptrStudent;
    ptrStudent = new Student;

    ptrStudent->setMath(8);
    ptrStudent->setEnglish(10);
    cout << "Studant average 1: " <<ptrStudent->getAverage()<<endl;

    ptrStudent->setMath(6);
    ptrStudent->setEnglish(7);
    cout << "Studant average 2: " <<ptrStudent->getAverage()<<endl;

    delete ptrStudent;

    return 0;
}