⬅ Previous Next ➡

Advanced OOP Concepts

Advanced OOP Concepts in C++
  • This section covers advanced OOP topics: virtual destructors, vtable, multiple inheritance issues, object slicing, and smart pointer basics.
  • These concepts are important for writing safe polymorphic code and avoiding memory leaks.

1) Virtual Destructor

  • If a base class is used polymorphically, its destructor should be virtual.
  • Otherwise deleting a derived object using base pointer may not call derived destructor (memory leak risk).
#include <iostream>
using namespace std;

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

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

int main() {
    Base *p = new Derived();
    delete p; // calls Derived destructor then Base destructor
    return 0;
}

2) vtable (Virtual Table) - Concept

  • When a class has virtual functions, compiler creates a hidden table called vtable.
  • Each object stores a hidden pointer (often called vptr) to the vtable.
  • At runtime, vtable helps decide which overridden function to call (dynamic dispatch).
  • Note: vtable/vptr are compiler implementation details, but concept is used to explain runtime polymorphism.
// Concept only (no direct access):
// Base* p = new Derived();
// p->show();  // decided at runtime using vtable

3) Multiple Inheritance Issues

3.1) Ambiguity Problem
  • If two base classes have same function name, derived class may face ambiguity.
  • Solution: use scope resolution Base1::fun().
#include <iostream>
using namespace std;

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

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

class C : public A, public B { };

int main() {
    C obj;
    obj.A::show();
    obj.B::show();
    return 0;
}
3.2) Diamond Problem (Hybrid Inheritance)
  • Occurs when a class inherits from two classes that both inherit from same base class.
  • Creates duplicate base members in derived class.
  • Solution: virtual inheritance.
#include <iostream>
using namespace std;

class A {
public:
    int x = 10;
};

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

class D : public B, public C { };

int main() {
    D obj;
    cout << obj.x << endl; // only one copy of A due to virtual inheritance
    return 0;
}

4) Object Slicing

  • When a derived object is assigned to a base object (by value), derived part is sliced off.
  • Use base pointer/reference to avoid slicing and keep polymorphic behavior.
#include <iostream>
using namespace std;

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

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

int main() {
    Derived d;

    Base b = d;     // slicing happens here
    b.show();       // prints Base

    Base &ref = d;  // no slicing
    ref.show();     // prints Derived

    return 0;
}

5) Smart Pointer Basics

  • Smart pointers automatically manage memory and prevent leaks.
  • Defined in <memory>.
  • Common types:
    • unique_ptr - single owner (best default)
    • shared_ptr - multiple owners (reference counting)
    • weak_ptr - non-owning reference to shared_ptr (prevents cycles)
5.1) unique_ptr Example
#include <iostream>
#include <memory>
using namespace std;

class Demo {
public:
    Demo() { cout << "Created\n"; }
    ~Demo() { cout << "Destroyed\n"; }
};

int main() {
    unique_ptr<Demo> p = make_unique<Demo>();
    // auto deleted when p goes out of scope
    return 0;
}
5.2) shared_ptr Example
#include <iostream>
#include <memory>
using namespace std;

int main() {
    shared_ptr<int> p1 = make_shared<int>(10);
    shared_ptr<int> p2 = p1; // shared ownership

    cout << "Value: " << *p1 << endl;
    cout << "Use count: " << p1.use_count() << endl;

    return 0;
}

6) Quick Notes

  • Use virtual destructor in polymorphic base classes.
  • vtable enables runtime dispatch for virtual functions.
  • Multiple inheritance can cause ambiguity and diamond problem (use virtual inheritance).
  • Object slicing happens when copying derived to base by value.
  • Prefer smart pointers over raw new/delete in modern C++.
⬅ Previous Next ➡