Chapter 15 Intermediate 58 Questions

Practice Questions — Inheritance in C++

← Back to Notes
11 Easy
11 Medium
11 Hard

Topic-Specific Questions

Question 1
Easy
What is the output of the following code?
#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A "; }
};
class B : public A {
public:
    B() { cout << "B "; }
};
int main() {
    B b;
    return 0;
}
Constructor order: base first, then derived.
A B
Question 2
Easy
What is the output?
#include <iostream>
using namespace std;
class Base {
public:
    int x;
    Base() : x(10) {}
};
class Derived : public Base {
public:
    int y;
    Derived() : y(20) {}
};
int main() {
    Derived d;
    cout << d.x << " " << d.y << endl;
    return 0;
}
Derived inherits x from Base. Both x and y are public.
10 20
Question 3
Easy
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A "; }
    ~A() { cout << "~A "; }
};
class B : public A {
public:
    B() { cout << "B "; }
    ~B() { cout << "~B "; }
};
int main() {
    B b;
    return 0;
}
Constructors: base first. Destructors: derived first (reverse order).
A B ~B ~A
Question 4
Easy
What is the output?
#include <iostream>
using namespace std;
class Animal {
public:
    void eat() { cout << "Eating" << endl; }
};
class Dog : public Animal {
public:
    void bark() { cout << "Barking" << endl; }
};
int main() {
    Dog d;
    d.eat();
    d.bark();
    return 0;
}
Dog inherits eat() from Animal and has its own bark().
Eating
Barking
Question 5
Easy
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A "; }
};
class B : public A {
public:
    B() { cout << "B "; }
};
class C : public B {
public:
    C() { cout << "C "; }
};
int main() {
    C c;
    return 0;
}
Multilevel inheritance: A -> B -> C. Constructors run top to bottom.
A B C
Question 6
Medium
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A "; }
    ~A() { cout << "~A "; }
};
class B {
public:
    B() { cout << "B "; }
    ~B() { cout << "~B "; }
};
class C : public A, public B {
public:
    C() { cout << "C "; }
    ~C() { cout << "~C "; }
};
int main() {
    C c;
    return 0;
}
Multiple inheritance: base classes constructed in declaration order (A first, then B).
A B C ~C ~B ~A
Question 7
Medium
What is the output?
#include <iostream>
using namespace std;
class Base {
public:
    void show() { cout << "Base" << endl; }
};
class Derived : public Base {
public:
    void show() { cout << "Derived" << endl; }
};
int main() {
    Derived d;
    d.show();
    d.Base::show();
    return 0;
}
d.show() calls Derived's version. d.Base::show() explicitly calls the base version.
Derived
Base
Question 8
Medium
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    A(int x) { cout << "A(" << x << ") "; }
};
class B : public A {
public:
    B(int x) : A(x * 2) { cout << "B(" << x << ") "; }
};
class C : public B {
public:
    C(int x) : B(x + 1) { cout << "C(" << x << ") "; }
};
int main() {
    C c(5);
    return 0;
}
C(5) calls B(6), which calls A(12). Trace the values.
A(12) B(6) C(5)
Question 9
Medium
What is the output?
#include <iostream>
using namespace std;
class Base {
protected:
    int x;
public:
    Base(int v) : x(v) {}
};
class D1 : public Base {
public:
    D1(int v) : Base(v) {}
    int get() { return x; }
};
class D2 : public Base {
public:
    D2(int v) : Base(v) {}
    int get() { return x * 2; }
};
int main() {
    D1 a(10);
    D2 b(10);
    cout << a.get() << " " << b.get() << endl;
    return 0;
}
D1 and D2 both inherit from Base but compute differently from the protected x.
10 20
Question 10
Medium
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A "; }
};
class B {
public:
    B() { cout << "B "; }
};
class C : public B, public A {
    A memberA;
    B memberB;
public:
    C() { cout << "C "; }
};
int main() {
    C c;
    return 0;
}
Order: base classes (declaration order B, A), then members (declaration order memberA, memberB), then C's body.
B A A B C
Question 11
Hard
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A "; }
};
class B : virtual public A {
public:
    B() { cout << "B "; }
};
class C : virtual public A {
public:
    C() { cout << "C "; }
};
class D : public B, public C {
public:
    D() { cout << "D "; }
};
int main() {
    D d;
    return 0;
}
Virtual base A is constructed only once, before any non-virtual bases. Then B, C, D.
A B C D
Question 12
Hard
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    int x;
    A() : x(0) {}
};
class B : public A {};
class C : public A {};
class D : public B, public C {
public:
    void set(int v) {
        B::x = v;
        C::x = v * 10;
    }
    void show() {
        cout << B::x << " " << C::x << endl;
    }
};
int main() {
    D d;
    d.set(5);
    d.show();
    return 0;
}
Without virtual inheritance, D has two separate copies of A. B::x and C::x are different variables.
5 50
Question 13
Hard
What is the output?
#include <iostream>
using namespace std;
class Base {
public:
    int x;
    Base(int v) : x(v) { cout << "Base(" << v << ") "; }
};
class Mid : virtual public Base {
public:
    Mid(int v) : Base(v) { cout << "Mid(" << v << ") "; }
};
class Leaf : public Mid {
public:
    Leaf(int v) : Base(v * 10), Mid(v) { cout << "Leaf(" << v << ") "; }
};
int main() {
    Leaf l(3);
    cout << endl << l.x << endl;
    return 0;
}
In virtual inheritance, the most derived class (Leaf) calls the virtual base constructor. Mid's call to Base is ignored.
Base(30) Mid(3) Leaf(3)
30
Question 14
Hard
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    A() { cout << "A "; }
    ~A() { cout << "~A "; }
};
class B : virtual public A {
public:
    B() { cout << "B "; }
    ~B() { cout << "~B "; }
};
class C : virtual public A {
public:
    C() { cout << "C "; }
    ~C() { cout << "~C "; }
};
class D : public B, public C {
public:
    D() { cout << "D "; }
    ~D() { cout << "~D "; }
};
int main() {
    D d;
    cout << endl;
    return 0;
}
Virtual base A constructed once, first. Destruction is reverse of construction.
A B C D
~D ~C ~B ~A
Question 15
Hard
What is the output?
#include <iostream>
using namespace std;
class Base {
public:
    void show() { cout << "Base" << endl; }
};
class Derived : private Base {
public:
    void test() {
        show();  // OK: private inheritance, but accessible inside Derived
    }
};
int main() {
    Derived d;
    d.test();
    // d.show();  // Error: show() is private in Derived's context
    return 0;
}
With private inheritance, base public members become private in derived. Accessible inside Derived but not outside.
Base
Question 16
Hard
What is the output?
#include <iostream>
using namespace std;
class X {
public:
    X() { cout << "X "; }
};
class Y {
public:
    Y() { cout << "Y "; }
};
class A : virtual public X {
public:
    A() { cout << "A "; }
};
class B : virtual public X, virtual public Y {
public:
    B() { cout << "B "; }
};
class C : public A, public B {
public:
    C() { cout << "C "; }
};
int main() {
    C c;
    return 0;
}
Virtual bases are constructed first (in the order they first appear): X then Y. Then non-virtual: A, B. Then C.
X Y A B C
Question 17
Hard
What is the output?
#include <iostream>
using namespace std;
class Greet {
public:
    void hello() { cout << "Hello "; }
};
class D1 : public Greet {
public:
    void hello() { cout << "Hi "; }
};
class D2 : public D1 {
public:
    void test() {
        hello();
        D1::hello();
        Greet::hello();
    }
};
int main() {
    D2 d;
    d.test();
    return 0;
}
hello() without qualifier calls the nearest version (D1). Scope resolution calls specific versions.
Hi Hi Hello
Question 18
Medium
What happens when you compile this?
#include <iostream>
using namespace std;
class Base {
private:
    int secret;
public:
    Base(int s) : secret(s) {}
};
class Derived : public Base {
public:
    Derived(int s) : Base(s) {}
    void show() {
        cout << secret << endl;
    }
};
int main() {
    Derived d(10);
    d.show();
    return 0;
}
secret is private in Base. Can Derived access it directly?
Compilation error: 'secret' is a private member of 'Base'
Question 19
Easy
What is the output?
#include <iostream>
using namespace std;
class Vehicle {
public:
    Vehicle() { cout << "V "; }
};
class Car : public Vehicle {
public:
    Car() { cout << "C "; }
};
class SportsCar : public Car {
public:
    SportsCar() { cout << "S "; }
};
int main() {
    SportsCar sc;
    return 0;
}
Multilevel: Vehicle -> Car -> SportsCar. Constructors run base to derived.
V C S
Question 20
Medium
What is the output?
#include <iostream>
using namespace std;
class Base {
public:
    Base(int x) { cout << "B(" << x << ") "; }
    ~Base() { cout << "~B "; }
};
class Derived : public Base {
public:
    Derived(int x) : Base(x * 2) { cout << "D(" << x << ") "; }
    ~Derived() { cout << "~D "; }
};
int main() {
    Derived d(5);
    return 0;
}
Derived(5) calls Base(10). Constructors: base first. Destructors: derived first.
B(10) D(5) ~D ~B
Question 21
Hard
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    int x;
    A(int v = 0) : x(v) { cout << "A(" << v << ") "; }
};
class B : virtual public A {
public:
    B(int v) : A(v) { cout << "B "; }
};
class C : virtual public A {
public:
    C(int v) : A(v) { cout << "C "; }
};
class D : public B, public C {
public:
    D(int v) : A(v * 10), B(v), C(v) { cout << "D "; }
};
int main() {
    D d(5);
    cout << d.x << endl;
    return 0;
}
Most derived class D calls A(50). B and C's calls to A are ignored. Only one A exists.
A(50) B C D 50
Question 22
Easy
What is the output?
#include <iostream>
using namespace std;
class Animal {
public:
    string sound() { return "..."; }
};
class Cat : public Animal {
public:
    string sound() { return "Meow"; }
};
class Kitten : public Cat {
public:
    string sound() { return "Mew"; }
};
int main() {
    Kitten k;
    cout << k.sound() << endl;
    cout << k.Cat::sound() << endl;
    cout << k.Animal::sound() << endl;
    return 0;
}
Direct call uses Kitten's version. Scope resolution calls the specific class version.
Mew
Meow
...
Question 23
Medium
What is the output?
#include <iostream>
using namespace std;
class X { public: X() { cout << "X "; } ~X() { cout << "~X "; } };
class Y { public: Y() { cout << "Y "; } ~Y() { cout << "~Y "; } };
class Z : public Y, public X {
public:
    Z() { cout << "Z "; }
    ~Z() { cout << "~Z "; }
};
int main() { Z z; cout << endl; return 0; }
Declaration order is Y, X. Construction follows declaration order, not alphabetical.
Y X Z
~Z ~X ~Y

Mixed & Application Questions

Question 1
Easy
What are the five types of inheritance in C++?
Think about how many base and derived classes are involved and how they connect.
Single (one base, one derived), Multiple (two or more bases, one derived), Multilevel (chain: A -> B -> C), Hierarchical (one base, multiple derived), and Hybrid (combination of two or more types).
Question 2
Easy
In what order are constructors called in a multilevel inheritance chain A -> B -> C?
Think top to bottom.
A's constructor first, then B's, then C's. Destructors run in the reverse order: ~C, ~B, ~A.
Question 3
Easy
What is the output?
#include <iostream>
using namespace std;
class Shape {
public:
    void draw() { cout << "Shape" << endl; }
};
class Circle : public Shape {
public:
    void draw() { cout << "Circle" << endl; }
};
int main() {
    Circle c;
    c.draw();
    return 0;
}
The Circle object calls its own draw(), which hides Base::draw().
Circle
Question 4
Easy
What is the output?
#include <iostream>
using namespace std;
class Parent {
public:
    Parent() { cout << "Parent "; }
    ~Parent() { cout << "~Parent "; }
};
class Child : public Parent {
public:
    Child() { cout << "Child "; }
    ~Child() { cout << "~Child "; }
};
int main() {
    Child* c = new Child();
    delete c;
    return 0;
}
Dynamic allocation. Constructor: Parent then Child. Destructor: Child then Parent.
Parent Child ~Child ~Parent
Question 5
Medium
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    void greet() { cout << "Hello from A" << endl; }
};
class B {
public:
    void greet() { cout << "Hello from B" << endl; }
};
class C : public A, public B {
public:
    void greetBoth() {
        A::greet();
        B::greet();
    }
};
int main() {
    C c;
    c.greetBoth();
    c.A::greet();
    return 0;
}
c.greet() would be ambiguous, but A::greet() and B::greet() disambiguate.
Hello from A
Hello from B
Hello from A
Question 6
Medium
What is the output?
#include <iostream>
using namespace std;
class Base {
public:
    void show() { cout << "Base" << endl; }
};
class Mid : public Base {
public:
    void show() {
        Base::show();
        cout << "Mid" << endl;
    }
};
class Leaf : public Mid {
public:
    void show() {
        Mid::show();
        cout << "Leaf" << endl;
    }
};
int main() {
    Leaf l;
    l.show();
    return 0;
}
Leaf::show calls Mid::show, which calls Base::show. The chain unfolds.
Base
Mid
Leaf
Question 7
Medium
What is the output?
#include <iostream>
using namespace std;
class Base {
protected:
    int val;
public:
    Base(int v) : val(v) {}
};
class Derived : protected Base {
public:
    Derived(int v) : Base(v) {}
    int get() { return val; }
};
class GrandChild : public Derived {
public:
    GrandChild(int v) : Derived(v) {}
    int getDouble() { return val * 2; }
};
int main() {
    GrandChild g(5);
    cout << g.get() << " " << g.getDouble() << endl;
    return 0;
}
protected inheritance makes Base's protected val stay protected in Derived. GrandChild can still access it.
5 10
Question 8
Hard
What is the output?
#include <iostream>
using namespace std;
class V {
public:
    int x;
    V(int v = 0) : x(v) { cout << "V(" << v << ") "; }
};
class A : virtual public V {
public:
    A(int v) : V(v) { cout << "A "; }
};
class B : virtual public V {
public:
    B(int v) : V(v) { cout << "B "; }
};
class C : public A, public B {
public:
    C(int v) : V(v * 100), A(v), B(v) { cout << "C "; }
};
int main() {
    C c(3);
    cout << endl << c.x << endl;
    return 0;
}
The most derived class C calls V(300). A and B's calls to V are ignored.
V(300) A B C
300
Question 9
Hard
What is the output?
#include <iostream>
using namespace std;
class A {
public:
    int x;
    A(int v = 0) : x(v) {}
};
class B : virtual public A {
public:
    B(int v) : A(v) {}
};
class C : virtual public A {
public:
    C(int v) : A(v) {}
};
class D : public B, public C {
public:
    D(int v) : A(v), B(v + 1), C(v + 2) {}
};
int main() {
    D d(10);
    cout << d.x << " " << d.B::x << " " << d.C::x << endl;
    return 0;
}
With virtual inheritance, there is only one A. B::x and C::x both refer to the same x.
10 10 10
Question 10
Hard
What is the output?
#include <iostream>
using namespace std;
class Base {
public:
    Base() { cout << "Base "; }
    ~Base() { cout << "~Base "; }
};
class Member {
public:
    Member() { cout << "Member "; }
    ~Member() { cout << "~Member "; }
};
class Derived : public Base {
    Member m1;
    Member m2;
public:
    Derived() { cout << "Derived "; }
    ~Derived() { cout << "~Derived "; }
};
int main() {
    Derived d;
    cout << endl;
    return 0;
}
Order: base, members (in declaration order), then derived. Destruction is reverse.
Base Member Member Derived
~Derived ~Member ~Member ~Base

Multiple Choice Questions

MCQ 1
What is the syntax for public inheritance in C++?
  • A. class Derived extends Base
  • B. class Derived : public Base
  • C. class Derived implements Base
  • D. class Derived -> Base
Answer: B
B is correct. C++ uses the colon syntax: class Derived : public Base. Java uses extends (A) and implements (C). The arrow syntax (D) is not valid.
MCQ 2
In single inheritance, how many base classes does a derived class have?
  • A. Zero
  • B. Exactly one
  • C. Two
  • D. Unlimited
Answer: B
B is correct. Single inheritance involves exactly one base class and one derived class. Multiple inheritance involves two or more base classes.
MCQ 3
What is the order of constructor calls in inheritance?
  • A. Derived first, then Base
  • B. Base first, then Derived
  • C. Random order
  • D. Only Base constructor runs
Answer: B
B is correct. The base class constructor always runs before the derived class constructor. This ensures the base part is fully initialized before the derived part uses it.
MCQ 4
Which inheritance type is NOT supported in Java but IS supported in C++?
  • A. Single inheritance
  • B. Multilevel inheritance
  • C. Multiple class inheritance
  • D. Hierarchical inheritance
Answer: C
C is correct. Java does not support multiple class inheritance (a class extending two classes). C++ supports it. Java uses interfaces instead.
MCQ 5
With public inheritance, how do base class public members appear in the derived class?
  • A. private
  • B. protected
  • C. public
  • D. Not accessible
Answer: C
C is correct. Public inheritance preserves access levels: base public stays public, base protected stays protected. This models the "is-a" relationship.
MCQ 6
What is the diamond problem in C++?
  • A. A class that inherits from itself
  • B. A class that inherits from two classes that share a common base, causing duplicate base members
  • C. A class with no constructor
  • D. A circular dependency between header files
Answer: B
B is correct. The diamond problem occurs when class D inherits from B and C, and both B and C inherit from A. Without virtual inheritance, D gets two copies of A's members.
MCQ 7
How does virtual inheritance solve the diamond problem?
  • A. By preventing multiple inheritance entirely
  • B. By ensuring only one copy of the shared virtual base exists in the most derived class
  • C. By making all members public
  • D. By converting classes to structs
Answer: B
B is correct. Virtual inheritance ensures that a shared base class is included only once in the inheritance hierarchy, regardless of how many paths lead to it.
MCQ 8
In virtual inheritance, who is responsible for calling the virtual base class constructor?
  • A. The immediate derived class
  • B. The most derived class
  • C. The compiler automatically handles it
  • D. The virtual base itself
Answer: B
B is correct. With virtual inheritance, the most derived class in the hierarchy must call the virtual base class constructor. Intermediate classes' calls to the virtual base constructor are ignored.
MCQ 9
With private inheritance, how do base class public members appear in the derived class?
  • A. public
  • B. protected
  • C. private
  • D. Not accessible at all
Answer: C
C is correct. Private inheritance makes all inherited members private in the derived class. They are accessible within the derived class but not from outside or from further derived classes.
MCQ 10
What determines the order of base class construction in multiple inheritance?
  • A. The order in the initializer list
  • B. Alphabetical order
  • C. The order of declaration in the class definition
  • D. The size of each base class
Answer: C
C is correct. Base classes are constructed in the order they appear in the class definition (class D : public B, public A constructs B first, then A), regardless of the initializer list order.
MCQ 11
In a virtual inheritance hierarchy, when are virtual bases constructed relative to non-virtual bases?
  • A. After all non-virtual bases
  • B. Before all non-virtual bases
  • C. Interleaved based on declaration order
  • D. It depends on the compiler
Answer: B
B is correct. Virtual base classes are always constructed first, before any non-virtual base classes, regardless of where they appear in the inheritance declarations.
MCQ 12
What is the difference between method hiding and method overriding?
  • A. They are the same thing
  • B. Hiding uses virtual, overriding does not
  • C. Hiding occurs without virtual (static binding); overriding occurs with virtual (dynamic binding)
  • D. Hiding only works with private methods
Answer: C
C is correct. When a derived class defines a method with the same name as a non-virtual base method, it hides the base version (resolved at compile time). When the base method is virtual and the derived method has the same signature, it overrides it (resolved at runtime via vtable).
MCQ 13
If class D : private Base, can a class E : public D access Base's originally public members?
  • A. Yes, because E inherits publicly from D
  • B. No, because Base's members became private in D and are not accessible to E
  • C. Yes, but only if E uses a friend function
  • D. Yes, through protected access
Answer: B
B is correct. Private inheritance makes all Base members private in D. When E inherits from D, those members are not accessible to E (private members are not inherited further).
MCQ 14
What happens if the most derived class does NOT explicitly call the virtual base constructor?
  • A. Compilation error
  • B. The default constructor of the virtual base is called
  • C. The intermediate class's call is used
  • D. The program crashes at runtime
Answer: B
B is correct. If the most derived class does not explicitly call the virtual base constructor, the compiler uses the default constructor (if available). If no default constructor exists, it is a compilation error.
MCQ 15
Can a derived class access the private members of its base class?
  • A. Yes, always
  • B. Only with public inheritance
  • C. No, private members are never accessible in derived classes
  • D. Only if the base class is a struct
Answer: C
C is correct. Private members of a base class are never directly accessible in derived classes, regardless of the inheritance mode (public, protected, or private).
MCQ 16
Which type of inheritance models the 'implemented-in-terms-of' relationship?
  • A. public inheritance
  • B. protected inheritance
  • C. private inheritance
  • D. virtual inheritance
Answer: C
C is correct. Private inheritance means the derived class uses the base class's implementation but does not expose it. This models 'implemented-in-terms-of' rather than 'is-a'.
MCQ 17
What is hierarchical inheritance?
  • A. A chain of classes inheriting from each other
  • B. One base class with multiple derived classes
  • C. A class inheriting from multiple base classes
  • D. Inheritance using virtual keyword
Answer: B
B is correct. Hierarchical inheritance has one base class and multiple derived classes that independently extend it. Example: Shape is the base; Circle, Rectangle, Triangle are derived.
MCQ 18
In multiple inheritance, if both base classes have a method with the same name, what happens when the derived class calls it?
  • A. The first base class method is called
  • B. The second base class method is called
  • C. Compilation error due to ambiguity
  • D. Both methods are called
Answer: C
C is correct. If both base classes have a method with the same name and the derived class does not override it, calling the method is ambiguous and causes a compilation error. Use scope resolution (Base1::method()) to disambiguate.
MCQ 19
What is the destructor order in single inheritance (Base -> Derived)?
  • A. Base first, then Derived
  • B. Derived first, then Base
  • C. Only Derived destructor runs
  • D. Random order
Answer: B
B is correct. Destructors run in the reverse of construction order. For single inheritance, the derived destructor runs first, then the base destructor.
MCQ 20
What happens when you try to convert a Derived* to Base* with private inheritance?
  • A. Implicit conversion works normally
  • B. Only explicit static_cast works
  • C. The conversion is not allowed outside Derived's member functions and friends
  • D. Runtime error
Answer: C
C is correct. With private inheritance, the base class is a private implementation detail. The derived-to-base conversion is only accessible inside the derived class's own member functions and friends, not from outside code.

Coding Challenges

Challenge 1: University Hierarchy with Multilevel Inheritance

Easy
Create a Person class (name, age), a Student class that extends Person (rollNumber, semester), and a GraduateStudent that extends Student (thesisTopic, advisor). Show constructor/destructor order and demonstrate accessing inherited members.
Sample Input
Name: Priya, Age: 23, Roll: 101, Semester: 6, Thesis: ML in Healthcare, Advisor: Dr. Mehta
Sample Output
Person(Priya) Student(101) GraduateStudent() Priya, 23, Roll: 101, Sem: 6 Thesis: ML in Healthcare, Advisor: Dr. Mehta ~GraduateStudent ~Student ~Person
Use protected for name and age. Call base constructors explicitly. Show destruction order.
#include <iostream>
#include <string>
using namespace std;

class Person {
protected:
    string name;
    int age;
public:
    Person(string n, int a) : name(n), age(a) {
        cout << "Person(" << name << ") ";
    }
    ~Person() { cout << "~Person "; }
};

class Student : public Person {
protected:
    int rollNumber;
    int semester;
public:
    Student(string n, int a, int r, int s)
        : Person(n, a), rollNumber(r), semester(s) {
        cout << "Student(" << rollNumber << ") ";
    }
    ~Student() { cout << "~Student "; }
    void showStudent() {
        cout << name << ", " << age << ", Roll: " << rollNumber
             << ", Sem: " << semester << endl;
    }
};

class GraduateStudent : public Student {
    string thesis;
    string advisor;
public:
    GraduateStudent(string n, int a, int r, int s, string t, string adv)
        : Student(n, a, r, s), thesis(t), advisor(adv) {
        cout << "GraduateStudent()" << endl;
    }
    ~GraduateStudent() { cout << "~GraduateStudent "; }
    void showAll() {
        showStudent();
        cout << "Thesis: " << thesis << ", Advisor: " << advisor << endl;
    }
};

int main() {
    GraduateStudent g("Priya", 23, 101, 6, "ML in Healthcare", "Dr. Mehta");
    g.showAll();
    return 0;
}

Challenge 2: Multiple Inheritance: Printable + Loggable

Medium
Create a Printable class with a print() method and a Loggable class with a log() method. Create a Document class that inherits from both and has a title and content. Document's print() should call the base print logic and add its own. Demonstrate multiple inheritance.
Sample Input
Title: Report, Content: Quarterly earnings up 15%
Sample Output
[Printable] Sending to printer... Document: Report Quarterly earnings up 15% [Loggable] Logged at timestamp Document Report logged
Use multiple inheritance. Call base class methods with scope resolution.
#include <iostream>
#include <string>
using namespace std;

class Printable {
public:
    void print() { cout << "[Printable] Sending to printer..." << endl; }
};

class Loggable {
public:
    void log() { cout << "[Loggable] Logged at timestamp" << endl; }
};

class Document : public Printable, public Loggable {
    string title;
    string content;
public:
    Document(string t, string c) : title(t), content(c) {}
    void print() {
        Printable::print();
        cout << "Document: " << title << endl;
        cout << content << endl;
    }
    void log() {
        Loggable::log();
        cout << "Document " << title << " logged" << endl;
    }
};

int main() {
    Document doc("Report", "Quarterly earnings up 15%");
    doc.print();
    doc.log();
    return 0;
}

Challenge 3: Diamond Problem with Virtual Inheritance

Hard
Create a Device base class (serialNumber, powerOn/powerOff). Create Printer (printDoc) and Scanner (scanDoc) that virtually inherit from Device. Create AllInOne that inherits from both Printer and Scanner. Demonstrate that Device is constructed only once and the serial number is shared.
Sample Input
Serial: DEV-2026-001
Sample Output
Device(DEV-2026-001) constructed Printer constructed Scanner constructed AllInOne constructed Serial: DEV-2026-001 Powering on DEV-2026-001 Printing document... Scanning document... Powering off DEV-2026-001
Use virtual inheritance. Most derived class must call Device constructor. Show that serial number is not duplicated.
#include <iostream>
#include <string>
using namespace std;

class Device {
protected:
    string serialNumber;
    bool isOn;
public:
    Device(string sn = "") : serialNumber(sn), isOn(false) {
        cout << "Device(" << sn << ") constructed" << endl;
    }
    void powerOn() {
        isOn = true;
        cout << "Powering on " << serialNumber << endl;
    }
    void powerOff() {
        isOn = false;
        cout << "Powering off " << serialNumber << endl;
    }
    string getSerial() const { return serialNumber; }
};

class Printer : virtual public Device {
public:
    Printer(string sn) : Device(sn) {
        cout << "Printer constructed" << endl;
    }
    void printDoc() {
        cout << "Printing document..." << endl;
    }
};

class Scanner : virtual public Device {
public:
    Scanner(string sn) : Device(sn) {
        cout << "Scanner constructed" << endl;
    }
    void scanDoc() {
        cout << "Scanning document..." << endl;
    }
};

class AllInOne : public Printer, public Scanner {
public:
    AllInOne(string sn) : Device(sn), Printer(sn), Scanner(sn) {
        cout << "AllInOne constructed" << endl;
    }
};

int main() {
    AllInOne aio("DEV-2026-001");
    cout << "Serial: " << aio.getSerial() << endl;
    aio.powerOn();
    aio.printDoc();
    aio.scanDoc();
    aio.powerOff();
    return 0;
}

Challenge 4: Access Control Demonstration

Medium
Create a Base class with one public, one protected, and one private member. Create three derived classes: PublicChild (public inheritance), ProtectedChild (protected inheritance), and PrivateChild (private inheritance). In each, demonstrate which members are accessible inside the derived class and from main(). Create a GrandChild of PrivateChild to show that private inheritance stops further access.
Sample Input
Base members: pub=1, prot=2, priv=3
Sample Output
PublicChild: pub=1 prot=2 (priv not accessible) main: pd.pub=1 (prot, priv not accessible) ProtectedChild: pub=1 prot=2 (priv not accessible) main: cannot access any through ProtectedChild PrivateChild: pub=1 prot=2 (priv not accessible) GrandChild: cannot access any Base members
Show access results clearly. Use comments to indicate compilation errors.
#include <iostream>
using namespace std;

class Base {
public:
    int pub;
protected:
    int prot;
private:
    int priv;
public:
    Base() : pub(1), prot(2), priv(3) {}
};

class PublicChild : public Base {
public:
    void show() {
        cout << "PublicChild: pub=" << pub << " prot=" << prot
             << " (priv not accessible)" << endl;
    }
};

class ProtectedChild : protected Base {
public:
    void show() {
        cout << "ProtectedChild: pub=" << pub << " prot=" << prot
             << " (priv not accessible)" << endl;
    }
};

class PrivateChild : private Base {
public:
    void show() {
        cout << "PrivateChild: pub=" << pub << " prot=" << prot
             << " (priv not accessible)" << endl;
    }
};

class GrandChild : public PrivateChild {
public:
    void show() {
        // Cannot access pub or prot: they became private in PrivateChild
        cout << "GrandChild: cannot access any Base members" << endl;
    }
};

int main() {
    PublicChild pc;
    pc.show();
    cout << "main: pd.pub=" << pc.pub << " (prot, priv not accessible)" << endl;

    ProtectedChild ptc;
    ptc.show();
    cout << "main: cannot access any through ProtectedChild" << endl;

    PrivateChild pvc;
    pvc.show();

    GrandChild gc;
    gc.show();
    return 0;
}

Challenge 5: Constructor Order Tracer with Virtual and Non-Virtual Bases

Hard
Create a class hierarchy with virtual and non-virtual bases to demonstrate the exact construction and destruction order. Classes: V1 (virtual base), V2 (virtual base), N1 (non-virtual), N2 (non-virtual). Class Mid1 : virtual V1, N1. Class Mid2 : virtual V2, N2. Class Final : Mid1, Mid2. Print construction and destruction order.
Sample Input
Creating Final object
Sample Output
V1() V2() N1() Mid1() N2() Mid2() Final() ~Final() ~Mid2() ~N2() ~Mid1() ~N1() ~V2() ~V1()
Show that virtual bases are constructed first (before any non-virtual bases). Destruction is exact reverse.
#include <iostream>
using namespace std;

class V1 {
public:
    V1() { cout << "V1() "; }
    ~V1() { cout << "~V1() "; }
};

class V2 {
public:
    V2() { cout << "V2() "; }
    ~V2() { cout << "~V2() "; }
};

class N1 {
public:
    N1() { cout << "N1() "; }
    ~N1() { cout << "~N1() "; }
};

class N2 {
public:
    N2() { cout << "N2() "; }
    ~N2() { cout << "~N2() "; }
};

class Mid1 : virtual public V1, public N1 {
public:
    Mid1() { cout << "Mid1() "; }
    ~Mid1() { cout << "~Mid1() "; }
};

class Mid2 : virtual public V2, public N2 {
public:
    Mid2() { cout << "Mid2() "; }
    ~Mid2() { cout << "~Mid2() "; }
};

class Final : public Mid1, public Mid2 {
public:
    Final() { cout << "Final()" << endl; }
    ~Final() { cout << "~Final() "; }
};

int main() {
    Final f;
    return 0;
}

Need to Review the Concepts?

Go back to the detailed notes for this chapter.

Read Chapter Notes

Want to learn C++ with a live mentor?

Explore our C++ Masterclass