What is a Default Constructor?
A default constructor is a constructor that can be called with no arguments. It is called “default” because it creates an object with default values.
There are two types of default constructors:
- Compiler-provided default constructor
- User-defined default constructor
Compiler-provided Default Constructor
If you don’t define any constructor for your class, the compiler automatically creates a default constructor. This compiler-provided constructor:
- Takes no parameters
- Has an empty body
- Does nothing except call the default constructors of member objects
- Does not initialize fundamental type members (like int, float, etc.)
#include <iostream>
using namespace std;
class Example {
public:
int x; // Not initialized by compiler's default constructor
float y; // Not initialized by compiler's default constructor
};
int main() {
Example obj; // Compiler's default constructor called
// x and y will have garbage values
cout << "x = " << obj.x << ", y = " << obj.y << endl;
return 0;
}
User-defined Default Constructor
You can define your own default constructor to initialize member variables with specific values:
#include <iostream>
using namespace std;
class Student {
private:
string name;
int rollNumber;
float marks;
public:
// User-defined default constructor
Student() {
name = "Unknown";
rollNumber = 0;
marks = 0.0;
cout << "Default constructor called" << endl;
}
void display() {
cout << "Name: " << name << ", Roll: " << rollNumber;
cout << ", Marks: " << marks << endl;
}
};
int main() {
Student s; // User's default constructor called
s.display(); // Output: Name: Unknown, Roll: 0, Marks: 0.0
return 0;
}
When is the Default Constructor Called?
The default constructor is called in the following situations:
-
When objects are created without arguments:
Student s1; // Default constructor called -
When an array of objects is created:
Student students[3]; // Default constructor called 3 times -
When a derived class doesn’t call a base class constructor:
class Base { public: Base() { cout << "Base default constructor" << endl; } }; class Derived : public Base { public: Derived() { cout << "Derived default constructor" << endl; } // Base default constructor is implicitly called }; -
When dynamic objects are created without arguments:
Student* ptr = new Student(); // Default constructor called
Default Constructor with Default Arguments
You can create a constructor with default arguments that serves as a default constructor:
class Rectangle {
private:
double length;
double width;
public:
// Constructor with default arguments acts as a default constructor
Rectangle(double l = 1.0, double w = 1.0) {
length = l;
width = w;
}
double area() {
return length * width;
}
};
int main() {
Rectangle r1; // No arguments, uses defaults (1.0, 1.0)
Rectangle r2(5.0); // One argument (5.0, 1.0)
Rectangle r3(5.0, 3.0); // Two arguments (5.0, 3.0)
cout << "Area of r1: " << r1.area() << endl; // Output: 1.0
cout << "Area of r2: " << r2.area() << endl; // Output: 5.0
cout << "Area of r3: " << r3.area() << endl; // Output: 15.0
return 0;
}
When is the Compiler’s Default Constructor Not Provided?
The compiler doesn’t provide a default constructor in the following cases:
-
If you define any constructor (parameterized or copy):
class NoDefault { public: // Only parameterized constructor NoDefault(int x) { } // No default constructor provided by compiler }; int main() { // NoDefault obj; // Error: no default constructor NoDefault obj(10); // OK return 0; } -
If the class has const members or reference members:
class NoDefaultConst { private: const int x; // Const member int& y; // Reference member // These members require initialization in a constructor };
Why Define Your Own Default Constructor?
There are several reasons to define your own default constructor:
- Initialize members with meaningful default values
- Allocate resources needed by the object
- Set up the object’s initial state
- Ensure a valid object state even without explicit initialization
- Perform any necessary setup operations
Default Constructor and Member Initialization
You can use member initialization lists with default constructors:
class Person {
private:
string name;
int age;
public:
// Default constructor with initialization list
Person() : name("Unknown"), age(0) {
cout << "Default constructor called" << endl;
}
void display() {
cout << "Name: " << name << ", Age: " << age << endl;
}
};
Default Constructor in Inheritance
When you create an object of a derived class, the default constructor of the base class is automatically called before the derived class constructor:
#include <iostream>
using namespace std;
class Base {
public:
Base() {
cout << "Base default constructor" << endl;
}
};
class Derived : public Base {
public:
Derived() {
cout << "Derived default constructor" << endl;
}
};
int main() {
Derived d; // Output:
// Base default constructor
// Derived default constructor
return 0;
}
Common Mistakes with Default Constructors
-
Forgetting that defining other constructors removes the compiler’s default constructor:
class MyClass { public: MyClass(int x) { /* ... */ } // No default constructor! }; int main() { MyClass obj; // Error: no default constructor return 0; } -
Not initializing all members:
class PartialInit { private: int x, y, z; public: PartialInit() { x = 0; // y and z are not initialized! } }; -
Forgetting to add a default constructor when needed:
class NoDefault { // Parameterized constructor only NoDefault(int x) { /* ... */ } }; class Container { private: NoDefault member; // Requires NoDefault to have a default constructor! public: Container() { } // Error: cannot initialize 'member' };
Best Practices for Default Constructors
- Always provide a default constructor if your class will be stored in containers or arrays
- Initialize all member variables to avoid garbage values
- Use initialization lists for better performance
- Keep default constructor logic simple
- If you provide other constructors, consider providing a default constructor too
Summary
The default constructor is a special constructor that takes no arguments and initializes an object with default values. It can be provided by the compiler or defined by the programmer. Default constructors are essential for creating objects without explicit initialization, such as array elements or dynamically allocated objects. Understanding default constructors is crucial for proper object initialization in C++.