Mahesh
Mahesh

Reputation: 34615

virtual keyword in different scenarios

I figured out 2 different situations where virtual is used.

Are there any other situations where virtual is used ?

Upvotes: 0

Views: 216

Answers (7)

motoku
motoku

Reputation: 1581

The virtual keyword gives the function late binding. In late binding the function call is not bound to anything until run time. In polymorphism and at run time the class looks up its v-table to decide what overloaded function to call. The destructor is often virtual when its class is polymorphic. virtual is probably the most opposite to inline, and very similar (at least in my opinion) to extern.

Upvotes: 0

davogotland
davogotland

Reputation: 2777

there is actually one more little quirk with virtual. let's say you have a class which you would like to be what for example java, c#, php and actionscript would call abstract, but this class has no pure virtual methods. then you can declare the destructor as a pure virtual method in the class declaration, but still implement it. here's an example:

#include <iostream>

class MyAbstractClass
{
    public:
        MyAbstractClass(int i);
        virtual ~MyAbstractClass() = 0;
        int getI() const;
    private:
        int m_i;
};

class MyConcreteClass : public MyAbstractClass
{
    public:
        MyConcreteClass(int i);
        ~MyConcreteClass();
};

MyAbstractClass::MyAbstractClass(int i) :
    m_i(i)
{
    std::cout << "constructor of MyAbstractClass\n";
}

MyAbstractClass::~MyAbstractClass()
{
    std::cout << "destructor of MyAbstractClass\n";
}

int MyAbstractClass::getI() const
{
    return m_i;
}

MyConcreteClass::MyConcreteClass(int i) :
    MyAbstractClass(i)
{
    std::cout << "constructor of MyConcreteClass\n";
}

MyConcreteClass::~MyConcreteClass()
{
    std::cout << "destructor of MyConcreteClass\n";
}

int main(int argc, char* argv[])
{
    MyConcreteClass a(5);
    std::cout << a.getI();
    std::cout << std::endl;
    MyAbstractClass b(5); //compile error, can't instantiate a class with abstract functions

    return 0;
}

Upvotes: 0

James McNellis
James McNellis

Reputation: 354979

virtual always has the same meaning when applied to a member function. When a member function is virtual, it means that calls to that member function will be dispatched dynamically.

That is, the function to be called will be selected based on the dynamic type (the actual type), not the static type. Based on the actual type of the object, the final overrider of the virtual function will be called.

The only reason that destructors are "different" is that a derived class destructor has a different name than the base class destructor. The behavior of the derived class destructor is not affected by it being declared virtual, though: a derived class destructor always calls base class destructors after it has run.


As an example of the behavior of virtual functions:

struct B {
    void f() { }
    virtual void g() { }
};

struct D : B {
    void f() { }
    virtual void g() { }
};

int main() {
    B* p = new D();
}

The dynamic type of the expression *p is D because the actual type of the object pointed to by p is a D. You used new D() to create it, so it's dynamic type is D.

The static type of the expression *p is B because that is the type named in the code. Without running the program or evaluating what got assigned to p, the compiler doesn't know the most derived type of the object given by *p; it just knows that whatever it is, it is a B or something derived from B.

If you call p->f(), the call is dispatched statically because B::f is not virtual. The compiler looks at the static type of *p and selects the function to be called based on that (B::f).

If you call p->g(), the call is dispatched dynamically because B::g is virtual. At runtime, the dynamic type of the object is checked (using a vtable in many common implementations), and the final overrider is called. In this case, the final overrider is D::g because D is the most derived class that overrides B::g (if there was another class derived from D, it could opt to override B::g as well).

Upvotes: 1

Sarfaraz Nawaz
Sarfaraz Nawaz

Reputation: 361252

Example of virtual inheritance,

class UltimateBase{};
class Base1 : public virtual UltimateBase{};
class Base2 : public virtual UltimateBase {};

class Derived : public Base1, public Base2{};

So that instances of Derived class may have only one subobject of UltimateBase class.

Upvotes: 0

Nick
Nick

Reputation: 8317

virtual inheritance is a big one. among other things it resolves issues with duplicate members introduced by multiple inheritance. google "dreaded diamond pattern" for the full details there.

Upvotes: 0

Prasoon Saurav
Prasoon Saurav

Reputation: 92854

Virtual Base Class.

Also read C++-FAQ :What is the "dreaded diamond"?

Upvotes: 0

Fred Larson
Fred Larson

Reputation: 62053

There's also virtual inheritance, where the base class is referenced by an indirection.

In C++, what is a virtual base class?

Upvotes: 1

Related Questions