Constructors in c++
A Brief on classes :
In object-oriented languages, we use something called classes, which act as blueprints for our data. A class consists of properties and behavior. Properties are represented by class members, and behavior is defined using functions.
For instance, consider a banking application where we can create an Account class. This class could have properties like account ID, balance, account type, and other relevant data. To handle various transactions, the class’s behavior includes functions such as withdraw, deposit, and balance inquiry.
Once we have our general class set up, we can either make specific classes by using the basic one as a starting point or create several objects from that class. This is where constructors come in handy.
If a variable isn’t initialized, it could lead to unexpected behavior in objects. For secure programming, we usually aim to set the initial values for the class’s data members when creating objects.
#include <string>
#include <iostream>
class Account {
private:
int accountId;
float balance;
std::string type;
public:
void withdraw(float amount) { this->balance -= amount; }
float balanceInquiry() { return balance; }
void deposit(float amount) { this->balance += amount; }
};
int main() {
Account acc;
std::cout << acc.balanceInquiry() << std::endl;
return 0;
}
Executing the given code yielded an account balance of 2.8026e-45. This happens because the balance data member is uninitialized and contains garbage data. Ideally, we anticipate it to be 0.00 when a new object is created or set to a predefined amount. Let's see how we can use a constructor to fix this.
Constructors: Constructors are unique functions within a class. They run when an object is created, and we often use them to set initial values for the class’s data members and make sure they are initialized properly before anyone accesses them.
Syntax: A Constructor function name should be the same as its class name without any return type, for the above-mentioned Account class a constructor would look like Account();
Now let's use a constructor and initialize the variables.
#include <string>
#include <iostream>
class Account{
private:
int accountId;
float balance;
std::string type;
public:
//Constructor
Account(){
this->accountId = 0;
this->balance = 0.0;
this->type = "Savings";
}
void withdraw(float amuont){this->balance -= amuont;}
float balanceInquiry(){return balance;}
void deposit(float amount){this->balance += amount;}
};
int main(){
Account acc;
std::cout << acc.balanceInquiry() <<std::endl;
return 0;
}
Executing the given code yielded an account balance of 0.0 which is what we expected it to be.
Note that if no constructor is defined by us, the compiler will create an empty constructor that won't do any mentioned initialization. A constructor can also take some values to initialize the data with, and depending on the number and order of the parameters passed to a constructor, the constructor signature changes.
We can and usually, overload constructors depending on the programmer's use case, for example if you want to initialize the object with a minimum of 100.0 balance, we can define the constructor as :
#include <string>
#include <iostream>
class Account{
private:
int accountId;
float balance;
std::string type;
public:
//No args or default Constructor
Account(){
this->accountId = 0;
this->balance = 0.00;
this->type = "Savings";
}
//Overloaded Constructor
Account(float balance_val){
this->accountId = 0;
this->balance = balance_val;
this->type = "Savings";
}
void withdraw(float amuont){this->balance -= amuont;}
float balanceInquiry(){return balance;}
void deposit(float amount){this->balance += amount;}
};
int main(){
Account acc{100.0};
std::cout << acc.balanceInquiry() <<std::endl;
return 0;
}
By the way in the examples I have created an account class like Account acc or provided an initialization list like Account acc{100.0}, we can also use the new keyword and get a pointer to the object, and call the constructor like this:
Account * acc = new Account();
//or
Account * acc = new Account(100.0);
We can also use an initialization list to create a constructor for example the above constructor can be passed with an initialization list like :
Account():accountId{0},balance{0.0},type{"Current"}{
std::cout << "Constructor with initialisation list is called " << std::endl;
}
And if you want to create a constructor that takes arguments, it can be done like :
Account(int balance_value):accountId{0},balance{balance_value},type{"Current"}{
std::cout << "Constructor with initialisation list is called " << std::endl;
}
In the next posts, I will discuss different constructors like Delegating, Copy, and Move Constructors.
Feel free to ask questions or correct me and happy coding…