Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Virtual/pure virtual explained

Tags:

c++

virtual

What exactly does it mean if a function is defined as virtual and is that the same as pure virtual?

like image 644
Justin Avatar asked Aug 20 '09 15:08

Justin


4 Answers

From Wikipedia's Virtual function ...

In object-oriented programming, in languages such as C++, and Object Pascal, a virtual function or virtual method is an inheritable and overridable function or method for which dynamic dispatch is facilitated. This concept is an important part of the (runtime) polymorphism portion of object-oriented programming (OOP). In short, a virtual function defines a target function to be executed, but the target might not be known at compile time.

Unlike a non-virtual function, when a virtual function is overridden the most-derived version is used at all levels of the class hierarchy, rather than just the level at which it was created. Therefore if one method of the base class calls a virtual method, the version defined in the derived class will be used instead of the version defined in the base class.

This is in contrast to non-virtual functions, which can still be overridden in a derived class, but the "new" version will only be used by the derived class and below, but will not change the functionality of the base class at all.

whereas..

A pure virtual function or pure virtual method is a virtual function that is required to be implemented by a derived class if the derived class is not abstract.

When a pure virtual method exists, the class is "abstract" and can not be instantiated on its own. Instead, a derived class that implements the pure-virtual method(s) must be used. A pure-virtual isn't defined in the base-class at all, so a derived class must define it, or that derived class is also abstract, and can not be instantiated. Only a class that has no abstract methods can be instantiated.

A virtual provides a way to override the functionality of the base class, and a pure-virtual requires it.

like image 145
Diego Dias Avatar answered Oct 17 '22 08:10

Diego Dias


I'd like to comment on Wikipedia's definition of virtual, as repeated by several here. [At the time this answer was written,] Wikipedia defined a virtual method as one that can be overridden in subclasses. [Fortunately, Wikipedia has been edited since, and it now explains this correctly.] That is incorrect: any method, not just virtual ones, can be overridden in subclasses. What virtual does is to give you polymorphism, that is, the ability to select at run-time the most-derived override of a method.

Consider the following code:

#include <iostream>
using namespace std;

class Base {
public:
    void NonVirtual() {
        cout << "Base NonVirtual called.\n";
    }
    virtual void Virtual() {
        cout << "Base Virtual called.\n";
    }
};
class Derived : public Base {
public:
    void NonVirtual() {
        cout << "Derived NonVirtual called.\n";
    }
    void Virtual() {
        cout << "Derived Virtual called.\n";
    }
};

int main() {
    Base* bBase = new Base();
    Base* bDerived = new Derived();

    bBase->NonVirtual();
    bBase->Virtual();
    bDerived->NonVirtual();
    bDerived->Virtual();
}

What is the output of this program?

Base NonVirtual called.
Base Virtual called.
Base NonVirtual called.
Derived Virtual called.

Derived overrides every method of Base: not just the virtual one, but also the non-virtual.

We see that when you have a Base-pointer-to-Derived (bDerived), calling NonVirtual calls the Base class implementation. This is resolved at compile-time: the compiler sees that bDerived is a Base*, that NonVirtual is not virtual, so it does the resolution on class Base.

However, calling Virtual calls the Derived class implementation. Because of the keyword virtual, the selection of the method happens at run-time, not compile-time. What happens here at compile-time is that the compiler sees that this is a Base*, and that it's calling a virtual method, so it insert a call to the vtable instead of class Base. This vtable is instantiated at run-time, hence the run-time resolution to the most-derived override.

I hope this wasn't too confusing. In short, any method can be overridden, but only virtual methods give you polymorphism, that is, run-time selection of the most derived override. In practice, however, overriding a non-virtual method is considered bad practice and rarely used, so many people (including whoever wrote that Wikipedia article) think that only virtual methods can be overridden.

like image 32
Asik Avatar answered Oct 17 '22 09:10

Asik


The virtual keyword gives C++ its' ability to support polymorphism. When you have a pointer to an object of some class such as:

class Animal
{
  public:
    virtual int GetNumberOfLegs() = 0;
};

class Duck : public Animal
{
  public:
     int GetNumberOfLegs() { return 2; }
};

class Horse : public Animal
{
  public:
     int GetNumberOfLegs() { return 4; }
};

void SomeFunction(Animal * pAnimal)
{
  cout << pAnimal->GetNumberOfLegs();
}

In this (silly) example, the GetNumberOfLegs() function returns the appropriate number based on the class of the object that it is called for.

Now, consider the function 'SomeFunction'. It doesn't care what type of animal object is passed to it, as long as it is derived from Animal. The compiler will automagically cast any Animal-derived class to a Animal as it is a base class.

If we do this:

Duck d;
SomeFunction(&d);

it'd output '2'. If we do this:

Horse h;
SomeFunction(&h);

it'd output '4'. We can't do this:

Animal a;
SomeFunction(&a);

because it won't compile due to the GetNumberOfLegs() virtual function being pure, which means it must be implemented by deriving classes (subclasses).

Pure Virtual Functions are mostly used to define:

a) abstract classes

These are base classes where you have to derive from them and then implement the pure virtual functions.

b) interfaces

These are 'empty' classes where all functions are pure virtual and hence you have to derive and then implement all of the functions.

like image 114
JBRWilkinson Avatar answered Oct 17 '22 09:10

JBRWilkinson


In a C++ class, virtual is the keyword which designates that, a method can be overridden (i.e. implemented by) a subclass. For example:

class Shape 
{
  public:
    Shape();
    virtual ~Shape();

    std::string getName() // not overridable
    {
      return m_name;
    }

    void setName( const std::string& name ) // not overridable
    {
      m_name = name;
    }

  protected:
    virtual void initShape() // overridable
    {
      setName("Generic Shape");
    }

  private:
    std::string m_name;
};

In this case a subclass can override the the initShape function to do some specialized work:

class Square : public Shape
{
  public: 
    Square();
    virtual ~Square();

  protected:
    virtual void initShape() // override the Shape::initShape function
    {
      setName("Square");
    }
}

The term pure virtual refers to virtual functions that need to be implemented by a subclass and have not been implemented by the base class. You designate a method as pure virtual by using the virtual keyword and adding a =0 at the end of the method declaration.

So, if you wanted to make Shape::initShape pure virtual you would do the following:

class Shape 
{
 ...
    virtual void initShape() = 0; // pure virtual method
 ... 
};

By adding a pure virtual method to your class you make the class an abstract base class which is very handy for separating interfaces from implementation.

like image 32
Nick Haddad Avatar answered Oct 17 '22 09:10

Nick Haddad