Constructors
When an object is created, it should begin its lifetime in a properly initialized state. In this lesson, you will learn how C++ constructors initialize objects automatically and how default, parameterized, and overloaded constructors work.
Introduction
In the previous lesson, you learned how classes define types and how objects are created as instances of those types.
When an object is created, its data members need suitable initial values before the object is used. Requiring programmers to perform every initialization manually after object creation would make programs repetitive and error-prone.
Student student1;
student1.rollNumber = 101;
student1.name = "Rahul";C++ provides constructors to make initialization part of object creation itself.
Student student1(101, "Rahul");A constructor is used to initialize an object as its lifetime begins.
What is a Constructor?
A constructor is a special non-static member function used to initialize an object of a class type.
A constructor has the same name as its class and does not have a return type. It is selected and invoked as part of object initialization.
class Student
{
public:
Student()
{
// Constructor body
}
};Student student1;
│
▼
Student() Constructor
│
▼
Initialize student1
│
▼
Object Ready| Feature | Constructor |
|---|---|
| Purpose | Initialize an object |
| Name | Same as the class |
| Return Type | None |
| Invocation | Part of object initialization |
| Parameters | Can accept parameters |
| Overloading | Multiple constructors can exist |
A constructor prepares an object when that object is initialized.
Why Do We Need Constructors?
Objects often need valid initial state before they can be used safely. Constructors allow a class to control how its objects begin their lifetimes.
Without Proper Construction
- Fundamental data members may remain indeterminate.
- Initialization may be forgotten.
- The same setup code may be repeated.
- Objects may temporarily exist in invalid states.
With Constructors
- Initialization happens during object creation.
- Required values can be supplied immediately.
- Repeated setup code is reduced.
- Class invariants can be established early.
Automatic Initialization
Initialization is tied directly to object creation.
Valid State
Objects can begin their lifetimes with appropriate values.
Less Repetition
Common initialization logic can be centralized.
Required Data
Parameters can require important values during creation.
Flexible Creation
Overloaded constructors can support different initialization forms.
Better Class Design
The class controls how its objects are initialized.
Not every member automatically contains a garbage value. Fundamental members can be indeterminate when not initialized, while class-type members such as std::string are initialized by their own constructors.
Real-World Analogy
Imagine receiving a new smartphone. Before you can use it, the device needs an operating system, essential configuration, and initial settings.
A constructor serves a similar purpose for an object. It performs the initialization required when the object begins its lifetime.
| Smartphone Analogy | C++ |
|---|---|
| Phone model | Class type |
| Individual phone | Object |
| Initial setup | Constructor |
| Configuration values | Constructor arguments |
| Ready device | Initialized object |
📱 New Device
│
▼
⚙️ Initial Setup
│
▼
🔧 Configure State
│
▼
✅ Ready to UseCharacteristics of Constructors
Same Name
The constructor has the same name as its class.
No Return Type
A constructor has no return type, not even void.
Initialization
It participates in initializing an object.
Parameters
A constructor can accept parameters.
Overloading
A class can provide multiple constructors with different parameter lists.
Access Control
Constructors can use public, protected, or private access depending on the design.
Key Characteristics
- The constructor name matches the class name.
- Constructors do not declare a return type.
- Constructors participate in object initialization.
- Constructors can accept parameters.
- Constructors can be overloaded.
- Constructors can use member initializer lists.
- Constructors can have different access levels.
- Some constructors may be generated implicitly by the compiler.
A constructor is not an ordinary member function. It has special language rules and is used during object initialization.
Constructor Syntax
A constructor is declared inside the class using the class name and no return type.
class ClassName
{
public:
ClassName()
{
// Constructor body
}
};class Student
{
public:
Student()
{
// Initialization logic
}
};| Part | Meaning |
|---|---|
| Student | Constructor name and class name |
| () | Parameter list |
| { } | Constructor body |
| public: | Makes the constructor accessible from outside the class |
// ❌ Incorrect
void Student()
{
}
// ✅ Correct
Student()
{
}Writing void before a constructor changes the declaration into something that is not a valid constructor declaration.
When is a Constructor Called?
A constructor is invoked as part of object initialization. The constructor selected depends on the form of initialization and the arguments provided.
Student student1;Student student1;
Student student2(101);
Student student3(102, "Amit");| Object | Arguments | Selected Constructor |
|---|---|---|
| student1 | None | Student() |
| student2 | 101 | Student(int) |
| student3 | 102, "Amit" | Student(int, std::string) |
The compiler selects a viable constructor based on the initialization syntax and supplied arguments.
Example 1: Default Constructor
A default constructor is a constructor that can be called with no arguments.
#include <iostream>
class Student
{
public:
Student()
{
std::cout << "Constructor Executed";
}
};
int main()
{
Student student1;
return 0;
}Step-by-Step Explanation
- The Student class defines a constructor named Student().
- The constructor requires no arguments.
- student1 is declared as an object of type Student.
- Student() is invoked during the initialization of student1.
- The constructor body displays a message.
Constructor ExecutedA default constructor is one that can be invoked without arguments.
Example 2: Initializing Data Members
Constructors are commonly used to give data members suitable initial values.
#include <iostream>
#include <string>
class Student
{
public:
int rollNumber;
std::string name;
Student()
: rollNumber(101), name("Rahul")
{
}
};
int main()
{
Student student1;
std::cout << student1.rollNumber << std::endl;
std::cout << student1.name;
return 0;
}The syntax after the constructor parameter list is called a member initializer list. It initializes the data members before the constructor body executes.
Student()
: rollNumber(101), name("Rahul")
{
}Execution
- student1 begins initialization.
- rollNumber is initialized with 101.
- name is initialized with Rahul.
- The constructor body executes.
- Object initialization completes.
- The initialized values are displayed.
101
RahulPrefer member initializer lists for initializing data members instead of default-initializing them first and assigning values later inside the constructor body.
Default vs Parameterized Constructors
Constructors can initialize every object with the same values or accept arguments so that different objects begin with different state.
Default Constructor
- Can be called with no arguments.
- Useful for default initialization.
- Can establish standard initial values.
- Example: Student().
Parameterized Constructor
- Accepts one or more parameters.
- Uses supplied values during initialization.
- Allows different objects to begin with different state.
- Example: Student(int, std::string).
Student()
: rollNumber(0), name("Unknown")
{
}Student(int r, std::string n)
: rollNumber(r), name(n)
{
}| Feature | Default Constructor | Parameterized Constructor |
|---|---|---|
| Arguments Required | No | Yes |
| Initialization | Default values | Supplied values |
| Example Call | Student s1; | Student s2(101, "Rahul"); |
| Flexibility | Standard state | Custom state |
A default constructor means a constructor that can be called with no arguments. It does not simply mean a constructor written by the compiler.
Example 3: Parameterized Constructor
A parameterized constructor receives values during object creation and uses them to initialize the object.
#include <iostream>
#include <string>
class Student
{
public:
int rollNumber;
std::string name;
Student(int r, std::string n)
: rollNumber(r), name(n)
{
}
};
int main()
{
Student student1(101, "Rahul");
std::cout << student1.rollNumber << std::endl;
std::cout << student1.name;
return 0;
}Step-by-Step Explanation
- student1 is initialized with the arguments 101 and Rahul.
- The compiler selects Student(int, std::string).
- 101 is passed to parameter r.
- Rahul is passed to parameter n.
- rollNumber is initialized from r.
- name is initialized from n.
- The object is ready with its initial state.
Student student1(101, "Rahul");
│ │
│ └────► n
└────────────► r
r = 101
n = Rahul
│
▼
┌──────────────────────┐
│ rollNumber = 101 │
│ name = Rahul │
└──────────────────────┘101
RahulThe same parameterized constructor can initialize different objects with different values.
Constructor Overloading
Constructor overloading means defining multiple constructors in the same class with different parameter lists.
#include <string>
class Student
{
public:
int rollNumber;
std::string name;
Student()
: rollNumber(0), name("Unknown")
{
}
Student(int r)
: rollNumber(r), name("Unknown")
{
}
Student(int r, std::string n)
: rollNumber(r), name(n)
{
}
};Student s1;
Student s2(101);
Student s3(102, "Rahul");| Object | Initialization | Constructor Selected |
|---|---|---|
| s1 | No arguments | Student() |
| s2 | One integer | Student(int) |
| s3 | Integer and string | Student(int, std::string) |
Constructor overloading allows one class to support multiple valid ways of initializing its objects.
Memory Representation
Consider an object initialized using Student student1(101, "Rahul"). The constructor establishes the initial state of the object.
Student student1(101, "Rahul");student1
┌────────────────────────┐
│ rollNumber = 101 │
│ name = Rahul │
└────────────────────────┘The constructor itself is not stored separately inside every object. Non-static data members contribute to each object’s state, while member functions are part of the class definition.
| Component | Per Object? |
|---|---|
| Non-static data member values | Yes |
| Static data members | No |
| Member function code | No |
| Object state | Yes |
The object stores its state. The constructor is code used to initialize that state.
Constructor Execution Flow
Object initialization follows a defined sequence. Data members are initialized before the constructor body executes.
class Student
{
public:
int rollNumber;
std::string name;
Student(int r, std::string n)
: rollNumber(r), name(n)
{
std::cout << "Constructor body";
}
};Student student1(101, "Rahul");
│
▼
Select Matching Constructor
│
▼
Initialize rollNumber
│
▼
Initialize name
│
▼
Execute Constructor Body
│
▼
Object Initialization CompleteData members are initialized in the order they are declared in the class, not the order in which they appear in the member initializer list.
Real-World Applications
Constructors are used throughout software systems to establish the initial state of newly created objects.
Banking
Initialize account numbers, account holders, and opening balances.
Student Management
Initialize roll numbers, names, and course information.
Games
Initialize players, enemies, health values, and positions.
Healthcare
Initialize patient identifiers and record information.
E-Commerce
Initialize products, prices, inventory values, and orders.
Transport
Initialize vehicles, routes, drivers, and booking details.
BankAccount account(
"ACC101",
"Rahul",
5000.0
);Create Account
│
▼
Validate Required Values
│
▼
Initialize Account State
│
▼
Account ReadyAdvantages of Constructors
Automatic Setup
Initialization happens as part of object creation.
Reliable State
Objects can begin with valid values.
Reduced Repetition
Common initialization logic is centralized.
Required Information
Parameterized constructors can require important values.
Flexible Initialization
Overloading supports multiple creation forms.
Encapsulation
Initialization details can remain inside the class.
- Initialize objects as their lifetimes begin.
- Reduce repeated setup code.
- Help establish valid object state.
- Allow required information to be supplied during creation.
- Support different initialization forms through overloading.
- Keep initialization responsibilities inside the class.
Common Beginner Mistakes
Constructors do not have return types, including void.
The constructor name must match the class name exactly.
Constructors are used during initialization and are not called through an existing object like ordinary member functions.
If no constructor can be called with the supplied arguments, object initialization fails to compile.
Prefer member initializer lists when initializing data members.
Declaring certain constructors can prevent an implicit default constructor from being generated.
// ❌ Incorrect
void Student()
{
}
// ✅ Correct
Student()
{
}class Student
{
public:
// ❌ Wrong name
// Person() {}
// ✅ Correct
Student() {}
};Student student1;
// ❌ Incorrect
// student1.Student();class Student
{
public:
Student(int r)
{
}
};
// ❌ No matching constructor
// Student student1;
// ✅ Matching constructor
Student student2(101);Do not assume that a no-argument constructor always exists. Whether one is implicitly declared depends on the constructors declared by the class.
Best Practices
- Initialize data members instead of leaving important state unspecified.
- Prefer member initializer lists.
- Keep constructors focused on establishing valid object state.
- Use parameterized constructors when values are required.
- Provide a default constructor only when a meaningful default state exists.
- Use constructor overloading only when each form represents a clear initialization option.
- Avoid unnecessary complex work inside constructors.
- Avoid calling virtual functions from constructors when polymorphic behavior is expected.
- Use explicit for single-argument constructors when implicit conversion is not intended.
- Declare members in an order that matches their initialization dependencies.
class Student
{
private:
int rollNumber;
std::string name;
public:
Student(int r, std::string n)
: rollNumber(r), name(n)
{
}
};class Student
{
public:
explicit Student(int rollNumber)
{
}
};A constructor should make it clear what information an object requires to begin its lifetime in a useful state.
Frequently Asked Questions
What is a constructor?
A constructor is a special member function used to initialize an object of a class type.
Does a constructor have a return type?
No. A constructor has no return type, not even void.
When is a constructor invoked?
A constructor is invoked as part of object initialization.
What is a default constructor?
A default constructor is a constructor that can be called with no arguments.
What is a parameterized constructor?
A parameterized constructor accepts arguments that can be used to initialize the object.
Can a class have multiple constructors?
Yes. Constructors can be overloaded by providing different parameter lists.
What is constructor overloading?
Constructor overloading means defining multiple constructors in the same class with different parameter lists.
What is a member initializer list?
It is the syntax after the constructor parameter list that directly initializes base classes and data members before the constructor body executes.
Does the compiler always create a default constructor?
No. The rules depend on which constructors and other special member functions are declared by the class.
Can a constructor be private?
Yes. Private constructors are used in designs that restrict how objects can be created.
Can constructors return values?
No. Constructors do not have return types and do not return values.
Can constructors be overloaded?
Yes. Multiple constructors can exist as long as their parameter lists allow overload resolution to distinguish them.
Key Takeaways
- Constructors initialize objects.
- A constructor has the same name as its class.
- Constructors do not have return types.
- A default constructor can be called with no arguments.
- Parameterized constructors accept values during object initialization.
- Constructor overloading provides multiple initialization forms.
- The compiler selects a matching constructor based on the initialization arguments.
- Member initializer lists directly initialize data members.
- Data members are initialized before the constructor body executes.
- Members are initialized in declaration order.
- Constructors help objects begin their lifetimes in valid states.
- A no-argument constructor is not always generated automatically.
Summary
Constructors are special member functions used during object initialization. They allow a class to control how its objects begin their lifetimes.
A default constructor can initialize an object without arguments, while a parameterized constructor accepts values that allow different objects to begin with different state.
Constructor overloading allows a class to provide multiple valid initialization forms. The compiler selects an appropriate constructor according to the supplied arguments.
Member initializer lists are the preferred way to initialize data members because initialization occurs before the constructor body executes.
By designing constructors carefully, classes can reduce repetitive setup code and help ensure that objects begin their lifetimes in meaningful states.
Now that you understand how objects are initialized, the next lesson will introduce destructors, which are special member functions involved when an object’s lifetime ends.