Open In App

OOPs Interview Questions - C++ Programming

Last Updated : 08 Aug, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Object-Oriented Programming (OOP) is at the heart of C++, enabling code reusability, modularity, and scalability. In interviews, OOP-related questions are frequently asked to test your grasp of design, implementation, and real-world modeling using classes and objects.

Below is a well-structured article covering all key OOP concepts in C++ with common interview questions and brief, clear answers.

1. What is the difference between struct and class?

Following table lists the primary difference between struct and class:

Aspectstructclass
Default Access ModifierMembers are public by default.Members are private by default.
Memory AllocationCan be allocated on the stack or heap.Can be allocated on the stack or heap.
InheritanceSupports inheritance (with public, protected, or private access).Supports inheritance (with public, protected, or private access).
Use CaseOften used for Plain Old Data (POD) structures, or simple data grouping.Suitable for complex objects that may include methods, constructors, and destructors.

Example:

C++
#include <iostream>
using namespace std;

// Struct: members are public by default
struct MyStruct {
    int x;
    void show() {
        cout << "Struct x = " << x << endl;
    }
};

// Class: members are private by default
class MyClass {
    int y; // private by default
public:
    void setY(int val) { y = val; }
    void show() {
        cout << "Class y = " << y << endl;
    }
};

int main() {
    MyStruct s;
    s.x = 10;
    s.show();  // Accessible directly

    MyClass c;
    // c.y = 20;  //rror: private member
    c.setY(20); // Use public setter
    c.show();
    return 0;
}

2. What is the difference between function overloading and operator overloading?

Following is the main difference operator overloading and function overloading:

Function Overloading

Operator Overloading

It is basically defining a function in numerous ways such that there are many ways to call it or in simple terms you have multiple versions of the same functionIt is basically giving practice of giving a special meaning to the existing meaning of an operator or in simple terms redefining the pre-redefined meaning                          
Parameterized Functions are a good example of Function Overloading as just by changing the argument or parameter of a function you make it useful for different purposes Polymorphism is a good example of an operator overloading as an object of allocations class can be used and called by different classes for different purposes

Example of Function Overloading:

  1. int GFG(int X, int Y);
  2. int GFG(char X, char Y);

Example of Operator Overloading:

  1. int GFG() = X() + Y();
  2. int GFG() = X() - Y();

Example:

C++
#include <iostream>
using namespace std;

// Function Overloading
int add(int a, int b) {
    return a + b;
}

double add(double a, double b) {
    return a + b;
}

// Operator Overloading
class Point {
    int x;
public:
    Point(int val) : x(val) {}

    // Overloading + operator
    Point operator+(const Point& other) {
        return Point(x + other.x);
    }

    void show() {
        cout << "Point value: " << x << endl;
    }
};

int main() {
    // Function Overloading
    cout << "add(int, int): " << add(2, 3) << endl;
    cout << "add(double, double): " << add(2.5, 3.1) << endl;

    // Operator Overloading
    Point p1(5), p2(10);
    Point p3 = p1 + p2; // Uses overloaded +
    p3.show();

    return 0;
}

3. What is the difference between virtual functions and pure virtual functions?

Following are the major difference between virtual functions and pure virtual functions

Virtual Function

Pure Virtual Function

A Virtual Function is a member function of a base class that can be redefined in another derived class.A Pure Virtual Function is a member function of a base class that is only declared in a base class and defined in a derived class to prevent it from becoming an abstract class.
A virtual Function has its definition in its respective base class.              There is no definition in Pure Virtual Function and is initialized with a pure specifier (= 0).
The base class has a virtual function that can be represented or instanced; In simple words, its object can be made.A base class having pure virtual function becomes abstract that cannot be represented or instanced; In simple words, it means its object cannot be made.

Example:

C++
#include <iostream>
using namespace std;

// Base with virtual and pure virtual
class Base {
public:
    virtual void greet() {  // Virtual function
        cout << "Hello from Base" << endl;
    }

    virtual void pureGreet() = 0;  // Pure virtual function
};

// Derived implements pure virtual
class Derived : public Base {
public:
    void greet() override {
        cout << "Hello from Derived (Override)" << endl;
    }

    void pureGreet() override {
        cout << "Hello from Derived (Pure Virtual Implemented)" << endl;
    }
};

int main() {

    Derived d;
    Base* ptr = &d;

    ptr->greet();      // Calls overridden version
    ptr->pureGreet();  // Calls derived's implementation

    return 0;
}

4. Can a virtual function be called from a constructor? What happens when we do it?

Yes, you can call a virtual function from a constructor, but the base version of the function is called, not the derived one. During construction, the derived class part of the object is not yet constructed, so C++ resolves the call to the base class version.

Example:

C++
#include <iostream>
using namespace std;

class Base {
public:
    Base() { virtualFunc(); }
    virtual void virtualFunc() {
        cout << "Base version\n";
    }
};

class Derived : public Base {
public:
    void virtualFunc() override {
        cout << "Derived version\n";
    }
};

int main() {
    Derived d;
    return 0;
}

5. What is Function Overriding?

When a function of the same name, same arguments or parameters, and same return type already present/declared in the base class is used in a derived class is known as Function Overriding. It is an example of Runtime Polymorphism or Late Binding which means the overridden function will be executed at the run time of the execution.

Example:

C++
#include <iostream>
using namespace std;

class Animal {
public:
    // Virtual function allows overriding
    virtual void sound() {
        cout << "Animal makes a sound" << endl;
    }
};

class Dog : public Animal {
public:
    // Overrides the base class function
    void sound() override {
        cout << "Dog barks" << endl;
    }
};

int main() {
    Animal* a;       // Base class pointer
    Dog d;           // Derived class object
    a = &d;          // Base pointer points to derived object

    a->sound();      // Runtime polymorphism: Dog's version called
    return 0;
}

6. What happens if we define a virtual destructor but forget to mark the base class destructor as virtual?

If you delete a derived class object using a base class pointer and the base class destructor is not virtual, only the base part is destroyed. The derived class destructor is never called, leading to a memory/resource leak.

Example:

C++
#include <iostream>
using namespace std;

class Base {
public:
    ~Base() { cout << "Base Destructor\n"; }
};

class Derived : public Base {
public:
    ~Derived() { cout << "Derived Destructor\n"; }
};

int main() {
    Base* ptr = new Derived();
    delete ptr;
}

It's a silent issue no compile error, no crash, just leaked resources

7. Can constructors be private in C++? If yes, how are they used?

Yes! Private constructors are used in singleton design pattern and factory methods where object creation is restricted.

Example (Singleton Pattern):

C++
class Singleton {
private:
    Singleton() {}  // Private constructor
public:
    static Singleton& getInstance() {
        static Singleton instance;
        return instance;
    }
};

int main() {
    Singleton& s = Singleton::getInstance();
    // Singleton obj; // Error: constructor is private
}

Private constructors control instantiation, commonly used in design patterns.

8. When should we use multiple inheritance?

Multiple inheritances mean that a derived class can inherit two or more base/parent classes. It is useful when a derived class needs to combine numerous attributes/contracts and inherit some, or all, of the implementation from these attributes/contracts. To take a real-life example consider your Parents where Parent A is your DAD Parent B is your MOM and Chid C is you.

multiple inheritances
Multiple Inheritances

Example:

C++
#include <iostream>
using namespace std;

class Father {
public:
    void skills() {
        cout << "Father: Carpentry skills\n";
    }
};

class Mother {
public:
    void hobbies() {
        cout << "Mother: Gardening hobby\n";
    }
};

class Child : public Father, public Mother {
public:
    void identity() {
        cout << "Child: Inherits from both parents\n";
    }
};

int main() {
    Child c;
    c.identity();
    c.skills();    // Inherited from Father
    c.hobbies();   // Inherited from Mother
    return 0;
}

9. What is virtual inheritance?

Virtual inheritance is a technique that ensures only one copy of a base class's member variables is inherited by grandchild-derived classes. Or in simple terms, virtual inheritance is used when we are dealing with a situation of multiple inheritances but want to prevent multiple instances of the same class from appearing in the inheritance hierarchy.

Without Virtual Inheritance – Diamond Problem:

C++
#include <iostream>
using namespace std;

class A {
public:
    void show() {
        cout << "A's show()\n";
    }
};

class B : public A {};
class C : public A {};

class D : public B, public C {};

int main() {
    D obj;
    // obj.show();  Ambiguity: which A::show() to call?
}

With Virtual Inheritance- Solves Ambiguity:

C++
#include <iostream>
using namespace std;

class A {
public:
    void show() {
        cout << "A's show()\n";
    }
};

class B : virtual public A {};
class C : virtual public A {};

class D : public B, public C {};

int main() {
    D obj;
    obj.show();  // Ambiguity resolved
    return 0;
}

10. Can a derived class access private members of the base class? How?

Directly, No. But access is possible through:

  • Protected members (accessible)
  • Public/protected getters/setters
  • Friend classes/functions

Example:

C++
#include <iostream>
using namespace std;

class Base {
private:
    int x = 42;
    friend class Derived;  // Grant access
};

class Derived : public Base {
public:
    void show() {
        cout << "Accessing private x: " << x << endl;
    }
};

int main() {
    Derived d;
    d.show();
}

11. What are the different types of polymorphism in C++?

There is 2 type of polymorphism

Compile Time Polymorphism or Static Binding: This type of polymorphism is achieved during the compile time of the program which results in it making a bit faster than Run time. Also, Inheritance is not involved in it. It is comprised of 2 further techniques:

  • Function Overloading: When there are multiple functions with the same name but different parameters then this is known as function overloading.
C++
// same name different arguments
int GFG() {}
int GFG(int a) {}
float GFG(double a) {}
int GFG(int a, double b) {}
  • Operator Overloading: It is basically giving practice of giving a special meaning to the existing meaning of an operator or in simple terms redefining the pre-redefined meaning
C++
class GFG {
    // private and other modes
    statements public returnType
    operator symbol(arguments){ statements } statements
};

Run-Time Polymorphism or Late Binding: Run-time polymorphism takes place when functions are invoked during run time. 

  • Function Overriding: Function overriding occurs when a base class member function is redefined in a derived class with the same arguments and return type.
C++
// C++ program to demonstrate
// Function overriding
#include<iostream> 
using namespace std;
class GFG {
public:
    virtual void display()
    {
        cout << "Function of base class" << endl;
    }
};
class derived_GFG : public GFG {
public:
    void display()
    {
        cout << "Function of derived class" << endl;
    }
};
int main()
{
    derived_GFG dg;
    dg.display();
    return 0;
}

Output:

Function of derived class

12. What happens when we override a function but forget to use virtual in the base class?

If the base class function is not marked virtual, the call is resolved statically (compile-time), and function overriding doesn’t behave polymorphically.

Example:

C++
#include <iostream>
using namespace std;

class Base {
public:
    void show() { cout << "Base\n"; }
};

class Derived : public Base {
public:
    void show() { cout << "Derived\n"; }
};

int main() {
    Base* ptr = new Derived();
    ptr->show();  // Base version called
}

It seems correct but fails at runtime. It’s one of the most subtle and common C++ mistakes.

13. Explain the constructor & destructor in C++ .

A constructor is a special type of member function of a class, whose name is the same as that of the class by whom it is invoked and initializes value to the object of a class. 

There are 3 types of constructors:

A. Default constructor: It is the most basic type of constructor which accepts no arguments or parameters. Even if it is not called the compiler calls it automatically when an object is created.

Example:

C++
class Class_name {
public:
    Class_name() { cout << "I am a default constructor"; }
};


B. Parameterized constructor: It is a type of constructor which accepts arguments or parameters. It has to be called explicitly by passing values in the arguments as these arguments help initialize an object when it is created. It also has the same name as that of the class. 

Also, It is used to overload constructors.

Example:

C++
// CPP program to demonstrate
// parameterized constructors
#include <iostream>
using namespace std;
class GFG {
private:
    int x, y;

public:
    // Parameterized Constructor
    GFG(int x1, int y1)
    {
        x = x1;
        y = y1;
    }
    int getX() { return x; }
    int getY() { return y; }
};
int main()
{
    // Constructor called
    GFG G(10, 15);
    // Access values assigned by constructor
    cout << "G.x = " << G.getX() << ", G.y = " << G.getY();
    return 0;
}

Output

G.x = 10, G.y = 15

C. Copy Constructor: A copy constructor is a member function that initializes an object using another object of the same class. Also, the Copy constructor takes a reference to an object of the same class as an argument.

Example:

C++
Sample(Sample& t) { id = t.id; }

Destructors: Destructors are members of functions in a class that delete an object when an object of the class goes out of scope. Destructors have the same name as the class preceded by a tilde (~) sign. Also, destructors follow a down-to-top approach, unlike constructors which follow a top-to-down.

Syntax:

~constructor_name(); // tilde sign signifies that it is a destructor

14. What is object slicing in C++? How does it occur?

bject slicing occurs when a derived class object is assigned to a base class object (not a pointer or reference). The base part of the object is copied, but the derived-specific data is sliced off (i.e., lost).

Example:

C++
#include <iostream>
using namespace std;

class Base {
public:
    int x = 5;
    void print() { cout << "Base x = " << x << endl; }
};

class Derived : public Base {
public:
    int y = 10;
    void print() { cout << "Derived y = " << y << endl; }
};

int main() {
    Derived d;
    Base b = d;  // Object slicing
    b.print();   // Only base part copied
    // b.y;  // Error: y is sliced off
}

15. What is a virtual destructor?

When destroying instances or objects of a derived class using a base class pointer object, a virtual destructor is invoked to free up memory space allocated by the derived class object or instance. Virtual destructor guarantees that first the derived class destructor is called. Then the base class's destructor is called to release the space occupied by both destructors in the inheritance class which saves us from the memory leak. It is advised to make your destructor virtual whenever your class is polymorphic.

Example:

C++
#include <iostream>
using namespace std;

class Base {
public:
    Base() { cout << "Base constructor\n"; }
    virtual ~Base() { cout << "Base destructor\n"; }  // Must be virtual
};

class Derived : public Base {
public:
    Derived() { cout << "Derived constructor\n"; }
    ~Derived() { cout << "Derived destructor\n"; }
};

int main() {
    Base* ptr = new Derived();  // Base pointer to derived
    delete ptr;  // Correct destructor chain due to virtual destructor
}

16. Is destructor overloading possible? If yes then explain and if no then why?

The simple answer is NO we cannot overload a destructor. It is mandatory to only destructor per class in C++. Also to mention, Destructor neither take arguments nor they have a parameter that might help to overload.

Example:

C++
class MyClass {
public:
    ~MyClass() {}       
};

17. What do you know about friend class and friend function?

A friend class is a class that can access both the protected and private variables of the classes where it is declared as a friend.

Example of friend class:

C++
class Class_1st {
    // ClassB is a friend class of ClassA
    friend class Class_2nd;
    statements;
} class Class_2nd {
    statements;
}


A friend function is a function used to access the private, protected, and public data members or member functions of other classes. It is declared with a friend keyword. The advantage of a friend function is that it is not bound to the scope of the class and once it is declared in a class, furthermore to that, it cannot be called by an object of the class; therefore it can be called by other functions. Considering all the mentioned points we can say that a friend function is a global function.

Example of friend function:

C++
class GFG {
    statements;
    friend dataype function_Name(arguments);
    statements;
} OR class GFG {
    statements' friend int divide(10, 5);
    statements;
}

18. What are the C++ access modifiers?

The access restriction specified to the class members (whether it is member function or data member) is known as access modifiers/specifiers. 

Access Modifiers are of 3 types:

  1. Private - It can neither be accessed nor be viewed from outside the class 
  2. Protected - It can be accessed if and only if the accessor is the derived class
  3. Public - It can be accessed or be viewed from outside the class 

Example:

C++
#include <iostream>
using namespace std;

class Demo {
private:
    int a = 1;      // Not accessible outside class

protected:
    int b = 2;      // Accessible in derived class

public:
    int c = 3;      // Accessible from anywhere

    void show() {
        cout << "a = " << a << ", b = " << b << ", c = " << c << endl;
    }
};

class Derived : public Demo {
public:
    void access() {
        // cout << a << endl; Not allowed (private)
        cout << b << endl;    // Allowed (protected)
        cout << c << endl;    // Allowed (public)
    }
};

int main() {
    Derived d;        // Create object normally
    d.access();       // Call member function
    return 0;
}

19. What is an abstract class and when do you use it?

An abstract class is a class that is specifically designed to be used as a base class. An abstract class contains at least one pure virtual function. You declare a pure virtual function by using a pure specifier(= 0) in the declaration of a virtual member function in the class declaration

You cannot use an abstract class as a parameter type, a function return type, or the type of an explicit conversion, nor can you declare an object of an abstract class. However, it can be used to declare pointers and references to an abstract class. 

Example:

C++
#include <iostream>
using namespace std;

class Shape {
public:
    virtual void draw() = 0; // Pure virtual → makes Shape abstract
};

class Circle : public Shape {
public:
    void draw() override {
        cout << "Drawing Circle\n";
    }
};

int main() {
    Shape* ptr = new Circle();
    ptr->draw();    // Polymorphic behavior
    delete ptr;
}

An abstract class is used if you want to provide a common, implemented functionality among all the implementations of the component. Abstract classes will allow you to partially implement your class, whereas interfaces would have no implementation for any members whatsoever. In simple words, Abstract Classes are a good fit if you want to provide implementation details to your children but don't want to allow an instance of your class to be directly instantiated.

20. What are the static data members and static member functions?

The static data member of a class is a normal data member but preceded with a static keyword. It executes before main() in a program and is initialized to 0 when the first object of the class is created. It is only visible to a defined class but its scope is of a lifetime.

Syntax:

static Data_Type Data_Member; 

The static member function is the member function that is used to access other static data members or other static member functions. It is also defined with a static keyword. We can access the static member function using the class name or class objects.

Syntax:

classname::function name(parameter);

Example:

C++
#include <iostream>
using namespace std;

class Counter {
    static int count;  // Static data member
public:
    Counter() { ++count; }
    static void showCount() {  // Static function
        cout << "Count = " << count << endl;
    }
};

int Counter::count = 0;  // Initialize static member

int main() {
    Counter a, b, c;
    Counter::showCount();  // Call static function via class
}

21. Can we call a virtual function from a constructor?

Yes, we can call a virtual function from a constructor. But it can throw an exception of overriding.

Example:

C++
#include <iostream>
using namespace std;

class Base {
public:
    Base() {
        cout << "Base Constructor\n";
        virtualFunc();  // Calls Base version only
    }

    virtual void virtualFunc() {
        cout << "Base::virtualFunc()\n";
    }

    virtual ~Base() {}
};

class Derived : public Base {
public:
    void virtualFunc() override {
        cout << "Derived::virtualFunc()\n";
    }
};

int main() {
    Derived d;
    return 0;
}

During Base constructor execution, Derived is not yet constructed, so virtualFunc() is not overridden yet.

22. What happens when two base classes have a common base class? How does C++ handle it (Diamond Problem)?

This creates a Diamond Inheritance situation. Without virtual inheritance, the grandchild gets two copies of the topmost base class.

Example (Without virtual inheritance):

C++
#include <iostream>
using namespace std;

class A {
public:
    int x;
};

class B : public A {};
class C : public A {};

class D : public B, public C {
public:
    void setX() {
        B::x = 10;
        C::x = 20;
    }
};

int main() {
    D obj;
    obj.setX();
    cout << obj.B::x << " " << obj.C::x << endl;  // Two separate copies
}

Without virtual inheritance, the duplicated base class can lead to ambiguity, inconsistency, and wasted memory.


Article Tags :
Practice Tags :

Similar Reads