A good interview question based on a C++ polymorphism in oops

C++ Technical Interview Question on polymorphism in oops

  • Write a complete class stating function overriding feature in C++
  • Show the function call in main program.
  • Explain the concept of function overriding.
  • Take example of drawing multiple shapes e.g. circle and rectangle etc.

Interviewer Intent:

  • You know the concept and syntax of function overriding in C++
  • you can write class and program.
  • If you follow best coding practice and the things you care when write the code.

NOTE: As per question criteria, we will write code using interface, but, to describe the concept a basic example will be covered first.

Answer:

Function overriding concept is run time polymorphism in oops, in which functions get resolved on run time using VTABLE (Virtual table) by compiler.

If we have definition /declaration of a function in base class and want to have a definition of same function name in derive class and want to call derived function using base class pointer, then we need to override function. It’s simple, just we must make base class function virtual. for example,
Example if base class has a function definition:

class A{
public:
	virtual void foo(){
		cout<<" Base::A";
	}
};
class B:public A{
public:
	void foo(){
		cout<<" Derived::B"; } }; int main() { A *p = new B(); p->foo();
	delete p;
	
	return 0;
}

Example if base class has a function declaration(Interface):

Recommended to read C++ Interface and Pure virtual function.

//Interface
class IShape{
public:
	virtual void draw()=0;
};

//Derived class
class Circle:public IShape{
public:
	void draw();
};

//define the function
void Circle::draw(){

	cout<<"Circle"<<endl; } int main() { IShape *s = new Circle(); s->draw();
	delete s;
	
	return 0;
}

As a best practice, what we have taken care of in above program so for? Here are the points

  • We have used interface not a class to maintain loose coupling.
  • We have deallocated the dynamically allocated memory.

But, still we have missed one important point i.e. we should have written virtual destructor in the above base class to maintain the hierarchy of destructor call.

You can read here constructor and destructor call order in inheritance in C++. ( In short, constructor gets called from the base to derived class, and destructor call order is vice versa).

In the current program, derived class that is “Circle” class destructor will not be called, as we have not written virtual destructor in base class. Here is the example and output in which derived class destructor is not called.

In the above program lets write destructors in base class and derived class

//Interface
class IShape{
public:

	virtual void draw()=0;
		//destructor
	~IShape(){
		cout<<"Base destructor"<<endl;
	}
};

//Derived class
class Circle:public IShape{
public:
	void draw();

	//destructor
	~Circle(){
		cout<<"Circle destructor"<<endl;
	}
};

//define the function
void Circle::draw(){

	cout<<"Circle"<<endl;
}

Output:

Circle
Base destructor

But, if we make base class destructor virtaul as virtual ~IShape()then derived class destructor will also be called and output will be as below in reverse order(derived to base)

Circle
Circle destructor
Base destructor

There is no harm if we have not written virtual destructor, but, a pain comes at later point in a large project, if some other programmer comes and deallocate memory consuming resources in the destructor of derived class. A memory leak will happen and it may take huge time identifying that at run time. so, as a best practice we should write virtual destructor in base class too.

You can read virtual destructor in C++ with example in detail.

Related Posts