Ian Russell
Ian Russell

Reputation: 53

Purpose of using a virtual function without overriding that virtual function

I am currently working through the Educative course Grokking the Coding Interview. While it is a very good course and does explain the algorithms very well, it does not always explain the code.

A few times I have seen the use of virtual functions, as a dynamic function (to be clear, I mean functions that require the instantiation of an object in order to be called). From reading up on virtual functions, I gather that they are used to achieve some OOP principles such as run time polymorphism, or just generally improving the maintainability of some code. In the case of these algorithms questions, that seems to be completely unnecessary. In fact, I am able to just delete the virtual keyword and the code runs all the same.

My question is: Why might the author be using virtual to define these functions?

Here is an example of the course's author's use of virtual functions:

using namespace std;

#include <iostream>
#include <queue>
#include <vector>

class MedianOfAStream {
 public:
  priority_queue<int> maxHeap;                             // containing first half of numbers
  priority_queue<int, vector<int>, greater<int>> minHeap;  // containing second half of numbers

  virtual void insertNum(int num) {
    if (maxHeap.empty() || maxHeap.top() >= num) {
      maxHeap.push(num);
    } else {
      minHeap.push(num);
    }

    // either both the heaps will have equal number of elements or max-heap will have one
    // more element than the min-heap
    if (maxHeap.size() > minHeap.size() + 1) {
      minHeap.push(maxHeap.top());
      maxHeap.pop();
    } else if (maxHeap.size() < minHeap.size()) {
      maxHeap.push(minHeap.top());
      minHeap.pop();
    }
  }

  virtual double findMedian() {
    if (maxHeap.size() == minHeap.size()) {
      // we have even number of elements, take the average of middle two elements
      return maxHeap.top() / 2.0 + minHeap.top() / 2.0;
    }
    // because max-heap will have one more element than the min-heap
    return maxHeap.top();
  }
};

int main(int argc, char *argv[]) {
  MedianOfAStream medianOfAStream;
  medianOfAStream.insertNum(3);
  medianOfAStream.insertNum(1);
  cout << "The median is: " << medianOfAStream.findMedian() << endl;
  medianOfAStream.insertNum(5);
  cout << "The median is: " << medianOfAStream.findMedian() << endl;
  medianOfAStream.insertNum(4);
  cout << "The median is: " << medianOfAStream.findMedian() << endl;
}

Again, from everything I've read, I really just don't see the point. And, running this exact code without the virtual keyword works just fine. My thinking would be that this is some sort of best practice in C++ land.

Thanks for any explanation!

Upvotes: 2

Views: 176

Answers (1)

Asteroids With Wings
Asteroids With Wings

Reputation: 17454

From reading up on virtual functions, I gather that they are used to achieve some OOP principles such as run time polymorphism

Yes.

or just generally improving the maintainability of some code

No.

In the case of these algorithms questions, that seems to be completely unnecessary. In fact, I am able to just delete the virtual keyword and the code runs all the same.

Yes.

My question is: Why might the author be using virtual to define these functions?

I see three possibilities here:

  1. The author will inherit this class in a later chapter, and has "got ready" by putting virtual on the member function declarations now. I think that's a bit of an odd choice, personally (particularly as they would also likely want to add a virtual destructor at that time), but maybe keep reading and find out!

  2. The author does it, always, out of habit, even when they don't need to. Some people like to make every function virtual so that you get dynamic polymorphism "by default", without having to change your base class when you later derive from it. I think that's also a very strange thing to do, personally.

  3. The author made a mistake.

a dynamic function (to be clear, I mean functions that require the instantiation of an object in order to be called)

We call those non-static member functions.

Upvotes: 2

Related Questions