Object-Oriented Programming: Constructors, Destructors, and Access Specifiers

Constructors: Definition and Fundamental Rules

  • Definition: A constructor is a special member function that runs automatically, exactly once, the moment an object is created; it is used to initialize its data.

  • Key Rules of Constructors:

    • Naming: A constructor must have the exact same name as the class.
    • Return Type: It has no return type, not even void.
    • Execution: It runs automatically upon object creation and is never called manually.
    • Parameters: It can take parameters (known as a parameterized constructor) to set real values during object creation.
    • Overloading Capabilities: It can be overloaded (having multiple constructors with different parameter lists) following the standard rules of function overloading.
  • Default vs. Parameterized Constructor Example:

class Student {
public:
    string name;
    int rollNo;

    // Default constructor — no parameters
    Student() {
        name = "Unknown";
        rollNo = 0;
    }

    // Overload #2 — parameterized constructor
    Student(string n, int r) {
        name = n;
        rollNo = r;
    }
};

Student s1;              // Uses default constructor
Student s2("Rahul", 101); // Uses parameterized constructor — this is overloading!

Constructor Overloading and Advanced Usage

  • Compiler Generation Behavior:

    • If no constructor is defined in a class, the compiler automatically generates a default zero-argument constructor.
    • If any constructor is explicitly written, C++ stops generating the default zero-argument constructor automatically.
    • Example: If only Student(string n, int r) is written in the class definition and Student s1; is declared, the code will fail to compile unless an explicit default constructor is also provided.
  • Member Initializer Lists:

    • A cleaner, more idiomatic way to write parameterized constructors in C++ utilizes a member initializer list instead of assignments in the constructor body.
    • Syntax Example:
  Student(string n, int r) : name(n), rollNo(r) {}
  // Same result as assigning in the body, but preferred in real code
  ```

# Destructors: Definition and Key Rules

* **Definition**: A destructor is a special member function that runs automatically the moment an object goes out of scope; it is used to clean up resources before the object is destroyed.
* **Key Rules of Destructors**:
  * **Naming**: A destructor has the exact same name as the class, preceded by a tilde symbol `~` (e.g., `~Student()`).
  * **Parameters and Return Type**: It accepts no parameters and has no return type.
  * **Overloading Restrictions**: It cannot be overloaded; there can only be **one** destructor per class.
  * **Execution**: It runs automatically when an object goes out of scope and is never called manually.

* **Destructor Implementation Example**:

cpp class Student { public: string name;

Student(string n) {
    name = n;
}

~Student() {
    cout << " destroyed";
}

};

# Object Destruction Order and Access Specifiers

* **LIFO Destruction Order**:
  * When multiple objects exist within a scope, their destructors execute in **LIFO (Last In, First Out)** order.
  * The most recently created object is destroyed first, exactly like unwinding a stack.
  * *Example Code*:

cpp { Student a("A"); // Created 1st Student b("B"); // Created 2nd } // Scope ends here -> destroys b first, then a   ```

  • Access Specifiers Summary:
    • Access specifiers control the accessibility of class members from various contexts:
Access SpecifierInside same class?Outside the class?From a derived (child) class?
publicyesyesyes
privateyesnono
protectedyesnoyes

Comprehensive Implementation Example

  • Full BankAccount Program:
    • The following end-to-end program demonstrates a parameterized constructor with validation, a setter method, a getter method, and a destructor functioning across an object's lifecycle.
#include <iostream>
#include <string>
using namespace std;

class BankAccount {
private:
    string accountHolder;
    double balance;

public:
    // Parameterized Constructor
    BankAccount(string name, double initialBalance) {
        accountHolder = name;
        balance = (initialBalance >= 0) ? initialBalance : 0;
        cout << "[Account Created for " << accountHolder << "]" << endl;
    }

    // Setter with Data Validation
    void deposit(double amount) {
        if (amount > 0) balance += amount;
    }

    // Getter
    double getBalance() {
        return balance;
    }

    // Destructor
    ~BankAccount() {
        cout << "[Memory Released for " << accountHolder << "]" << endl;
    }
};

int main() {
    BankAccount acc1("Rahul Verma", 5000.0); // Constructor runs -> prints "Account Created"
    acc1.deposit(1500.0);
    cout << "Final Balance: $" << acc1.getBalance() << endl;
    return 0;
} // acc1 goes out of scope here -> destructor runs automatically
  • Encapsulation in Action:
    • The constructor validates initialBalance prior to storing it (>= 0 or falls back to 0).
    • This functions as the primary checkpoint for incoming data, guaranteeing bad values never enter the object upon creation.

Viva & Technical Interview Questions

  • Q1: What is the main difference between a Class and a Structure in C++?

    • Answer: In a class, members are private by default. In a structure (struct), members are public by default.
  • Q2: Does a Constructor have a return type?

    • Answer: No. A constructor does not have any return type, not even void.
  • Q3: What is the difference between Encapsulation and Abstraction?

    • Answer: Encapsulation is the process of binding data and methods together to restrict direct access. Abstraction focuses on hiding internal implementation complexity and exposing only necessary interfaces.
  • Q4: Can a Destructor be overloaded?

    • Answer: No. A destructor takes no parameters and cannot be overloaded. A class can have only one destructor.
  • Q5: In what order are destructors called when multiple objects exist?

    • Answer: Destructors are called in LIFO (Last In, First Out) order. The last created object is destroyed first.
  • Q6: What happens if no constructor is defined in a class?

    • Answer: The compiler automatically generates a default zero-argument constructor.
  • Q7: Can constructors be overloaded, and if so, how?

    • Answer: Yes — a class can have multiple constructors as long as they differ in their parameter list, following the exact same rules as regular function overloading (different number, type, or order of parameters).