CodeSteps

Python, C, C++, C#, PowerShell, Android, Visual C++, Java ...

C++ – How to create an interface or an abstract class?

An interface is a contract between a caller and a callee. An interface doesn’t provide any implementation. It provides a blueprint. C++ uses a virtual keyword to create an interface or an abstract class.

Let’s take an example:

class IHello
{
public:
	virtual void SayHello() = 0;
};

IHello is an interface with the SayHello function prototype. We can’t create an instance for IHello class. Because this is an abstract class (a class with 0 or more pure virtual functions); it’s not possible to create an instance for these classes. The following code throws errors.

int main()
{
	IHello hello;

	return 0;
}

The above code will generate the below error:

error C2259: 'IHello' : cannot instantiate abstract class due to following members:
        'void IHello::SayHello(void)' : is abstract

The only way to create an instance for this class is to implement the SayHello function in its derived class and instantiate the derived class. The code looks like the below: This code will work without any errors.

class CHello : public IHello
{
public:
	void SayHello()
	{
		cout << "Hello!" << endl;
	}
};

int main()
{
	CHello hello;
	hello.SayHello();

	return 0;
}

Another place where C++ uses virtual keyword is at the class’s destructor. The class’s constructor is to construct a class; all the class’s initialization code goes here. The class’s destructor is to release any memory allocated to the class’s members.

The class’s constructor is called at the time of instantiating the class. This means at the time of creating an object of a class. The class’s destructor is called when the object is out of scope or the object is going to destruct.

In the case of inheritance, if we instantiate the derived class; first, the base class’s constructor will call before calling the derived class’s constructor. But destructors will call in reverse order; first, the derived class’s destructor will call before calling the base class’s destructor.

Look at the below example:

class Shape
{
public:
	Shape()
	{
		cout << "Shape's constructor called" << endl;
	}
	~Shape()
	{
		cout << "Shape's destructor called" << endl;
	}
};

class Circle : public Shape
{
public:
	Circle()
	{
		cout << "Circle's constructor called" << endl;
	}
	~Circle()
	{
		cout << "Circle's destructor called" << endl;
	}
};

int main()
{
	Circle circle;

	return 0;
}

Once you run this code, it will display the below result.

Shape's constructor called
Circle's constructor called
Circle's destructor called
Shape's destructor called

Observe the sequence of calling constructors and destructors. This is perfectly fine if it executes in the same order that we have seen. But in the case of destructors, there is a chance of altering the calling sequence of destructors.

Look at the below code:

int main()
{
	Shape *pShape = new Circle();
	if ( pShape != NULL )
	{
		delete pShape;
		pShape = NULL;
	}
}

This code just creates an object of “Circle” and if it is successfully created, destroys the object. The tricky part here is, the “Circle” object is assigned to the “Shape” type variable. This is acceptable; because the Shape class is the base class for Circle.

But when we run the program; it will show the below result:

Shape's constructor called
Circle's constructor called
Shape's destructor called

Observe that, Circle‘s destructor never called in this situation. Because Circle‘s instance is assigned to the Shape type variable. The compiler assumes that the object is of type Shape even though the actual object type is Circle. In this case, the compiler will depend on early binding (where types are resolved at compile time). But in our code, the types resolved at run-time (late-binding). So, the compiler is unable to recognize the actual type. Hence it was never called Circle‘s destructor.

To resolve this problem, add a virtual keyword to Shape‘s destructor. Let’s add the virtual keyword to the Shape class and re-run the application.

class Shape
{
public:
	Shape()
	{
		cout << "Shape's constructor called" << endl;
	}
	virtual ~Shape()
	{
		cout << "Shape's destructor called" << endl;
	}
};

After running this, the order of calling constructors and destructors, are proper and the results are as we expected.

We will discuss another place where the virtual keyword is used in C++, in our next article.

**

C++ – How to create an interface or an abstract class?

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top