Sometimes when programming, it may be necessary to initialise the objects' data members and member functions before carrying out any activities.
Data members are the variables that are defined in any class using either derived data types or basic data types (such as int, char, float, etc). (like class,
structure, pointer, etc.). Member functions are the ones that are defined inside the class declaration.
Let's say you are creating a video game. We need to set the initial location, health, acceleration, and a few other variables in that game to some default
value each time a new player registers.
To achieve this, separate functions for each quantity can be defined, and the quantities can then be given the necessary default values. Every time a new
player registers, we must call a set of routines to do this. This procedure can now grow drawn-out and challenging.
What if the quantities could be automatically assigned together with the new player's declaration? This can be accomplished more effectively and simply with a constructor.
A constructor is a method that has been specifically defined in a C++ class and is launched whenever an instance of that class is created. It is frequently employed for things like setting up class attributes in a new object. A constructor can accept arguments that help with initialization, just like with functions. When a new object is formed, the constructor method receives the arguments.
class logicmojo { public: // Constructor logicmojo() { // Constructor body. } };
⮞ The constructor's declaration and definition are shown in the aforementioned syntax. It is defined outside the class using the scope resolution operator, much like how we define a member function outside the class.
⮞ It is important to note that the constructor's name is the same as the name of its class. It is optional to include zero or more parameters in the constructor parameter list that is encased in square brackets.
⮞ Since they are called automatically when an object is created, the constructor should be declared in the class's public section.
The following are some differences between constructors and regular functions:
Constructor's name is the same as the class's
There is no return type for constructors.
An object's constructor is invoked automatically upon creation.
The C++ compiler creates a default constructor for us if we don't specify one (expects no parameters and has an empty body).
According to the design of our programme, a constructor may be made public, private, or protected. Constructors are typically made public because public methods may be accessed from anywhere and allow us to build a class object from any location in the code. Other classes cannot generate instances of a class with a private constructor. When object creation is not required, this is used. When a class only has static member functions, this situation occurs (i.e., the functions which are independent of any class object and can be accessed using a class name with scope resolution operator, i.e. ::).
Constructor functions cannot be referenced by addresses and cannot be inherited.
In C++, a constructor cannot be inherited. A derived class can, however, call the constructor of the base class. All of the base class's members and member methods,
including constructors, are contained in a derived class, also known as a child class.
In C++, the constructor cannot be virtual. For any class that has one or more virtual functions, a virtual table—also known as a vtable—is created. Regardless
of the type of reference used for the function call, virtual functions make sure the right function is called for an object. The base of the relevant vtable
is referenced by a "virtual-pointer" that is present in every object of this type. The vtable makes reference to the function address whenever
a virtual function is called.
However, no virtual table has yet been constructed in memory when a class constructor is called, hence no virtual pointer has yet been defined. A constructor cannot be declared virtual as a result.
Default constructors
These constructors don't pass any parameters or receive any input. Class C's default constructor is C::C. (). When a constructor is not defined, the compiler provides a default one.
Therefore, a line like "integer v1" uses the compiler's default constructor to generate the object v1.
// c++ program to illustrate the concept of constructors #include <iostream> using namespace std; class integer { public: int x, y; // Default Constructor declared integer() { x = 45; y = 10; } }; int main() { integer a; cout << "x: " << a.x << endl << "y: " << a.y; return 0; }
The compiler will implicitly supply a default constructor in the programme above.
Parameterized Constructor
It is not possible to initialise various objects with different starting values when using the default constructor. What if we have to supply constructors with arguments in order to instantiate an object? To address this problem, there is a distinct kind of constructor called a parameterized constructor.
A constructor with the ability to accept one or more arguments is known as a parameterized constructor. This makes it easier for programmers to create objects with a variety of beginning values.
// C++ program to illustrate parameterized constructors #include <iostream> using namespace std; class find_int { private: int a, b; public: // Parameterized Constructor find_int(int x, int y) { a = x; b = y; }; int getX() { return a; }; int getY() { return b; }; }; int main() { find_int v(10, 15); // Constructor called cout << "a = " << v.getX() << endl; // values assigned by constructor accessed cout<< "b = " << v.getY() << endl; return 0; }
NOTE: The type of the class to which a constructor function belongs cannot be one of the arguments.
Copy Constructors
We indicated that a constructor function's parameters cannot be the type of the class to which it belongs when we talked about parameterized
constructors.
Constructors, however, can take a class reference as a parameter. Copy constructors use another object of the same class to initialise a new object.
The following situations are used to call copy constructors in C++:
⮞ whenever the class's objects are returned as values.
⮞ whenever an object of the same class is used as a foundation for another object.
⮞ whenever parameters are supplied as objects.
// C++ program to illustrate copy constructor class integer { int a ,b; public: integer (integer &v) // copy constructor declared { a=v.a; b=v.b; }; };
Dynamic Constructor
A dynamic constructor is one that uses a dynamic memory allocator new in a constructor to dynamically allocate memory
(i.e., allocate memory to variables at runtime rather than at compile time) to variables. This allows us to initialise the objects dynamically.
The memory block that the object accesses, rather than the object's memory, is created by the dynamic constructor.
#include <iostream> using namespace std; class Emp_record { int* rem_project; public: // Default constructor. Emp_record() { // Allocating memory at run time. rem_project = new int; *rem_project = 0; } // Parameterized constructor. Emp_record(int x) { rem_project = new int; *rem_project = x; } void display() { cout << *rem_project << endl; } }; //main function int main() { // Default constructor would be called. Emp_record Emp_record1 = Emp_record(); cout << "Due projects for Emp_record1:\n"; Emp_record1.display(); // Parameterized constructor would be called. Emp_record Emp_record2 = Emp_record(10); cout << "Due projects for Emp_record2:\n"; Emp_record2.display(); return 0; }
Multiple constructors
The three constructor functions we've covered can all be used in the same class in C++.
Since no values were given by the calling programme to the first constructor function, the constructor assigned the
data values to itself.
The main function's suitable values are passed as parameters to the second constructor function by the function call.
The third constructor function's arguments are objects. The values of the first data element are set to their appropriate values by copy constructors.
class complex_no { int a, b; public: complex_no() // default constructor { a= 10; b=45; }; complex_no( int x, int y) // parameterized constructor { a=x; b=y; }; complex_no( complex_no & v) // copy constructor { a=v.a; b=v.b; }; };
Overloading of the constructor
This is the case when a class defines multiple constructor functions. The class name is the same for overloaded constructors, but they take a different number
of parameters.
They depend on the quantity and kind of parameters that the calling function received. Depending on the arguments given when the object is formed, the compiler will
know which constructor has to be run.
// C++ program to illustrate Constructor overloading #include <iostream> using namespace std; class Box_Shape { int a, b; public: // Constructor with no argument Box_Shape() { a= 2; b= 3; }; // constructor with one argument Box_Shape(int x) { a=b=x; }; // Constructor with two arguments Box_Shape(int x, int y) { a= x; b= y; }; int area(void) { return(a*b); }; void display() { cout<<"area="<< area() <<endl; }; }; int main() { // Constructor Overloading with two different constructors of class name Box_Shape s; Box_Shape s2(6); Box_Shape s3( 3, 2); s.display(); s.display(); s.display(); return 0; }
When is the copy constructor invoked?
A copy constructor may be called in C++ in the following circumstances:
when a class object is returned as a value.
when a class object is supplied as a parameter (by value) to a function.
when an item of the same class is built using another object as a basis.
when a temporary object is created by the compiler.
The C++ Standard permits the compiler to remove the copy in some circumstances, such as the return value optimization, therefore it is not guaranteed that
a copy constructor will be invoked in each of these scenarios.
When an object is destroyed, a member function called the destructor is immediately called. When an object exits the scope of a function, the destructor is immediately executed by the compiler, which also destroys any local objects that were created there. The destructor is named after the class name, but a tilde (~) is placed before the name. A destructor receives no parameters and has no return type.
⮞ When an object is removed, a destructor dealslocates the memory that it had taken up.
⮞ It is impossible to overload a destructor. Functions are declared with the same name in the same scope when overloading occurs, but each function has a separate definition and a different number of parameters. However, each class has a single destructor that does not take any arguments. A destructor cannot be overloaded as a result.
⮞ A destructor is always invoked after a constructor, in the opposite sequence. In C++, the Stack is used to allocate variables and objects. The Stack operates in a Last-In, First-Out (LIFO) fashion. As a result, memory deallocation and destruction are always done in the opposite sequence of allocation and creation. The code following demonstrates this.
⮞ Anywhere in the class definition can contain a destructor. However, a destructor is always defined at the end of the class definition to restore numerical order to the code.
#include <iostream> using namespace std; class depart { public: depart() { // Constructor is defined. cout << "Constructor Invoked for depart class" << endl; } ~depart() { // Destructor is defined. cout << "Destructor Invoked for depart class" << endl; } }; class emp_record { public: emp_record() { // Constructor is defined. cout << "Constructor Invoked for emp_record class" << endl; } ~emp_record() { // Destructor is defined. cout << "Destructor Invoked for emp_record class" << endl; } }; int main(void) { // Creating an object of depart. depart d1; // Creating an object of emp_record. emp_record e2; return 0; }
Explanation:
The constructor of the object named d1 is automatically called when the object is created in the first line of main(), i.e. (Department d1). As a result, "Constructor Invoked for Department class" appears in the first line of output. Similar to this, the compiler automatically calls the constructor for the Employee class when the e2 object of the Employee class is created in the second line of main(), i.e. (Employee e2). This causes the message "Constructor Invoked for Employee class" to be written.
A constructor is always called before a destructor, and vice versa. The destructor for object e2 is called first when the main function's scope expires. "Destructor Invoked for Employee class" is printed as a result. Object d1's destructor is then invoked, and the message "Destructor Invoked for Department class" is printed.
Constructors | Destructors |
---|---|
The compiler calls the constructor to initialise a class object. | When the instance is destroyed, the destructor is called. |
Constructors are able to accept parameters. | No parameters can be passed to the destructor. |
The constructor is used to initialise a class object and assign values to the class-specific data members. | While a class object's destructor is used to deallocate its memory. |
The same class may have more than one constructor. | There is only ever one destructor in a class. |
Overloaded constructors are possible. | You can't overload a destructor. |
What is a constructor's function?
A collection of random, illogical bits is transformed into a live thing by the constructor. Initializing the internal data members of the object, but also having the option to assign resources (memory, files, semaphores, sockets, and so on). The abbreviation "ctor" stands for "constructor."
What C++ constructors are executed in what order?
The execution proceeds from top to bottom in the inheritance tree, starting with the base class constructor and continuing with the derived class constructor.
Are virtual destructor possible? If true, what use do virtual destructors serve?
We can, yes. To ensure that the proper class destructor is called at run time, do this. Specifically, when we hold the object from the derived class using a base class pointer or reference. Without a virtual destructor, the only destructor that will be called is the destructor for the base class.
This concludes our discussion of "Constructor in C++." I sincerely hope that you learned something from it and that it improved your knowledge. You can consult the C++ Tutorial if you want to learn more about C++.
Good luck and happy learning!