
Understanding Constructors in C++
Constructors are special member functions of a class that run automatically when an object is created. Their job is to initialize (set up) the object’s internal state so it starts life in a valid, predictable configuration. In C++, constructors can be non-parameterized (default) or parameterized, and you can overload them (define multiple constructors with different parameter lists).
A constructor in C++ is a special member function that has the same name as its class, has no return type (not even
void
), and is invoked automatically when an object of that class is created to initialize its data members.
Why Do We Need Constructors?
Contents
- Correctness & Safety: Ensure every object starts in a valid state (no uninitialized data members).
- Convenience: Let callers provide values at creation time (parameterized), or get sensible defaults (non-parameterized).
- Maintainability: Centralize initialization logic in one place, reducing duplication and errors.
- Performance: Prefer member-initializer lists to initialize members directly (especially important for
const
members, references, and complex objects).
Structure of a Constructor
General form inside a class:
class ClassName {
public:
ClassName(); // non-parameterized (default) constructor
ClassName(Type1 p1, Type2 p2); // parameterized constructor (overload)
};
Definitions (outside the class):
ClassName::ClassName() { }
ClassName::ClassName(Type1 p1, Type2 p2)
: member1(p1), member2(p2) // ← member-initializer list
{
/* optional body */
}
Core rules to remember:
- Name: Must be exactly the class name.
- Return type: None (not even
void
). - Overloading: Allowed (different parameter lists).
- Initializer list: Prefer
: member(value)
to directly initialize members. Required forconst
members, references, or base-class initialization. - Initialization order: Members are initialized in the order of their declaration in the class, not the order in the initializer list.
- Access: Constructors can be
public
,protected
, orprivate
(useful for patterns like singletons or factories).
Types of Constructors
- Non-parameterized (Default) Constructor: Takes no arguments; supplies default values so objects are valid even when the caller provides nothing.
- Parameterized Constructor: Takes arguments; allows customized initialization at the time of object creation.
Non-Parameterized (Default) Constructor
Below is a student-friendly default-constructor version of your student
class. It gives safe defaults and a way to inspect the state.
#include <iostream>
using namespace std;
class student {
private:
int a; // private: internal detail
public:
int b; // public: accessible from outside
// Non-parameterized (default) constructor: gives safe defaults
student() {a=0; b=0 } // preferred: member-initializer list
void display() {
cout << "The value of a and b is: " << a << " and " << b << endl;
}
};
int main() {
student s; // calls default constructor → a=0, b=0
s.display(); // prints: The value of a and b is: 0 and 0
return 0;
}
Explanation
student() : {a=0, b=0 }
initializesa
andb
directly (efficient & clear).- Creating
student s;
automatically calls the default constructor, sos
starts with known values.
Parameterized Constructor
Here is your original sample (kept in your style), followed by notes and a best-practice variant.
// Online C++ compiler to run C++ program online
#include <iostream>
using namespace std;
class student {
private:
int a;
public:
int b;
// Parameterized constructor (from your sample)
student(int m, int n) {
a = m; // set private member a
b = n; // set public member b
}
void display() {
cout << "The value of a and b is:" << a << " and " << b << endl;
}
};
int main() {
student s(5, 10); // calls parameterized constructor with m=5, n=10
s.display(); // prints: The value of a and b is:5 and 10
return 0;
}
Line-by-line explanation
student(int m, int n) { ... }
is a parameterized constructor. It allows the caller to supply values fora
andb
right when the object is created.- In
main
,student s(5, 10);
constructss
and setsa=5
,b=10
. display()
prints both values to verify initialization worked.
Best-practice equivalent (using a member-initializer list):
class student {
private:
int a;
public:
int b;
// Preferred: initialize members directly
student(int m, int n) : a(m), b(n) { }
void display() {
cout << "The value of a and b is:" << a << " and " << b << endl;
}
};
Why prefer this? It constructs members in place with the given values (no default-then-assign), which is both clearer and often more efficient—and required for some member types.
Comparison Table
Feature | Non-parameterized (Default) Constructor | Parameterized Constructor |
---|---|---|
Arguments | None | Required (as declared) |
Initialization | Supplies default values so the object is valid out of the box | Uses caller-provided values for custom setup |
Flexibility | Lower (same defaults for all objects) | Higher (each object can differ at creation) |
Typical Use | Placeholders, safe defaults, when values aren’t known yet | When initial values are known / must be enforced |
Syntax (inside class) | ClassName(); | ClassName(T1 p1, T2 p2, ...); |
Definition (preferred) | ClassName() : m1(v1), m2(v2) { } | ClassName(T1 p1, T2 p2) : m1(p1), m2(p2) { } |
Example (student ) | student() : a(0), b(0) { } | student(int m, int n) : a(m), b(n) { } |
When it’s called | ClassName obj; | ClassName obj(arg1, arg2, ...); |
Notes | Guarantees a valid baseline state | Enforces required data at construction time |
Final Takeaways
- Use a default constructor to ensure objects are always constructible and safe by default.
- Provide a parameterized constructor to let callers supply meaningful values at creation time.
- Prefer member-initializer lists and remember that initialization order follows the class member declaration order, not the list order.
- It’s fine to have both constructors (overloading) so your class is flexible for students and real-world use.