tags:

views:

605

answers:

10

I am new to C++.

Could anybody tell me the difference between method overriding anf virtual function concepts in c++.

The functionality of virtual functions can be over-ridden in its derived classes. Redefining a function in a derived class is called function overriding.

why do we actually have virtual functions?

+6  A: 

Virtual function / method is simply a function whose behavior can be overriden within a subclass (or in C++ terms a derived class) by redefining how the function works (using the same signature).

Think of a base class mammal with a speak function. The function is void and simply couts how a mammal speaks. When you inherit from this class you can override the speak method so that dogs go "Arf Arf!" and cats go "Meow Meow".

Your question seems to ask what are the differences, well there are none because with virtual functions one can override the behavior of these functions. You may be after the difference between overriding functions and overloading them.

Overloading functions means to create a function with the same name but different arguments or return types. Here is an explanation on overloading in C++ from IBM's site:

Overloading (C++ only) If you specify more than one definition for a function name or an operator in the same scope, you have overloaded that function name or operator. Overloaded functions and operators are described in Overloading functions (C++ only) and Overloading operators (C++ only), respectively.

An overloaded declaration is a declaration that had been declared with the same name as a previously declared declaration in the same scope, except that both declarations have different types.

If you call an overloaded function name or operator, the compiler determines the most appropriate definition to use by comparing the argument types you used to call the function or operator with the parameter types specified in the definitions. The process of selecting the most appropriate overloaded function or operator is called overload resolution, as described in Overload resolution (C++ only).

http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=/com.ibm.xlcpp8a.doc/language/ref/overl.htm

JonH
In C++ terms "a derived class".
anon
@Neil - edited was more thinking in .net terms.
JonH
one minor nitpick: you say that overloading "means to create a function with the same name but different arguments or return types". I would just remove the "return types" part of that statement...they are not considered part of the overload resolution, at least in the current c++ standard.
Mike Ellery
+6  A: 

hello

Check out C++ FAQ lite, http://www.parashift.com/c++-faq-lite/. is probably one of the best C++ resources for beginners. it has in-depth write-up about virtual functions and overriding.

I personally found C++ FAQ to be an excellent source as I learn C++. Other people have different opinion, your mileage may vary

aaa
C++ FAQ is not introductory, its a reference.
Hassan Syed
If you don't already know C++, a FAQ telling you how your C++ sucks isn't going to help!
John Dibling
@John Dibling, maybe you are confusing the C++FAQ lite with the C++ FQA, the former being a compendium of frequently asked questions in comp.lang.c++, while the later is just a rant against the language based on dubious facts.
David Rodríguez - dribeas
@David Rodrigues - dribeas: I think your bias *for* C++ has skewed your perseption of Yossi Kreinin's writings. I'm a C++ fan myself, and I find http://yosefk.com/ *way* more informative than the parashift.com FAQ.
just somebody
@ just somebody. I haven't found a single useful thing in the "fqa". What was informative for you there?
Nemanja Trifunovic
A: 

The difference is just used when you call the method of the derived class, through a pointer to a base class object. In that moment you if the method you're calling was override in the derived class, you'll get the exceution of the base class, instead if was virtual then you got the execution of the derived class method.

#include <iostream>

class A{
    public:
    virtual void getA() { std::cout << "A in base" << std::endl;};
};

class B : public A {
    public:
    void getA() { std::cout << "A in derived class" << std::endl;}
};

int main(int argc, char** argv)
{
    A a;
    B b;
    a.getA();
    b.getA();

    A* t = new B;
    t->getA();
}

For example: in this program t->getA() print "A in derived class", but if there'were no virtual modificator in the base class A, then it would print "A in base".

Hope it helps.

erick2red
The standard clearly defines both `getA` methods in your examples as _overrides_. A virtual method in the base class and all definitions of the same method in derived classes are _overrides_, and they define the basic brick for polymorphism. When a method is not virtual you cannot override it, you can hide it by defining the same method in a derived class, but those will not _override_ the base class method.
David Rodríguez - dribeas
Why the down votes. Seems like a resonable explnation.
Martin York
@Martin York: The answer wrongly identifies _override_ with _redefine_. Only virtual functions can be _overrides_. The sentence: 'if the method you're calling was override in the derived class, you'll get the exceution of the base class' is associating the behavior of non-virtual not-overrides with the term override. When _overrides_ are present the implementation will call the most derived _override_, not the base. I guess my other comment is not clear on why I had downvoted.
David Rodríguez - dribeas
@david you realize that your explanation is a wordplay. I'm thinking here very practical, you can called, being conceptual, as you want, the point keep being the same. It's just a very high C++ developer who could tell about the real difference between 'override' and 'hiding' as you said. And besides everything depends on C++ implementations of very strict languages concepts, So i don't think my answer could missguide someone. Course no one would try to explain so big and discussed concepts with so a simple example. Try to understand a bit the one who's asking.
erick2red
@erick2red: the problem is that you got the 'override' part completely wrong. A virtual function in a derived class _overrides_ the base method. The behavior you wrote in the above quoted line is not the behavior that _overrides_ offer, but rather the behavior that non-overrides have. Since comments are too limited in space for a better explanation, I am following this discussion in the 'fake' answer here: http://stackoverflow.com/questions/2238928/why-do-we-actually-have-virtual-functions/2243224#2243224
David Rodríguez - dribeas
A: 

Helicopters and airplanes both fly, but they do it in different ways -- they are both instances of some hypothetical object Flyer . You can ask the Flyer object to "fly" -- but Flyer is just a interface It doesn't know anything about flying other than that it should be able to fly.

However if both the helicopter and airplane follow the interface of flyer, than if had an airfield object and you gave it a Flyer all the airfield needs to do is to request the flyers to fly.

For example:

Airplace X=Airplane X("boeing 747");
Airfield::takeoff(&X);

Helicopter Y= Helicopter("Comache");
Airfield::takeof(&Y);

void Airfield::takeOff(Flyer * f)
{
     f->fly();
}

C++ is a strict type-safe language, and this sort of functionality (making function calls to derived classes indirectly via a base class) is only possible when RTTI is enabled for the object hierarchy, and qualifying a member function virtual enables this.

Hassan Syed
@Hassan: RTTI in the sense most people mean when they think of C++ RTTI (i.e. the information required for the typeid operator and dynamic_cast) is not required for virtual method dispatch. Generally this requires only generation of one vtable per class and one vtable pointer per class instance. This is RTTI but not "RTTI" if you catch my drift. (Disclaimer: all above applies to most compilers but is in no way mandated by the ISO standard.)
Derrick Turk
A: 

Virtual functions exist to help design the behavior of a base class. A base class of pure virtual functions cannot be instantiated and is called an abstract class.

It's up to the derived classes to implement those methods described by the virtual functions in the base class. Derived classes can then be instantiated (they exist and occupy memory).

Deriving from derived classes can redfine a function already defined in the parent object. This technique you already know as overriding and allows you to customize the behavior of this child object.

As you learn more C++, you'll find that inheritance isn't all that it's cracked up to be. Composition and is often a better alternative. Have fun.

Mike Yam
+1  A: 

When coming from Java, one might find the concept of virtual vs. non virtual member functions confusing. The thing to remember is that Java methods correspond to virtual member functions in C++.

The question is not so much why we actually have virtual functions, but why do we have non-virtual ones? The way I justify them to myself (correct me if I'm wrong) is that they are cheaper to implement, as calls to them can be resolved at compile time.

Hans W
Then again, there are `final` methods in Java that are not meant to be overriden.
David Rodríguez - dribeas
The reason the choice was made in C++ is because it takes work to design a class for inheritance, particularly since there is no root class (think Object in Java). If the designer hasn't explicitly decided to make a class inheritable, it shouldn't be inherited from.
Joel
+2  A: 

The difference between function overriding and virtual function becomes important with polymorphism. Specifically when using references or pointers to a base class.

The Base Setup

In C++, any derived class can be passed to a function requiring a base class object. (See also Slicing and LSP). Given:

struct Base_Virtual
{
  virtual void some_virtual_function();
};

struct Base_Nonvirtual
{
  void some_function();
};

void Function_A(Base_Virtual * p_virtual_base);
void Function_B(Base_Nonvirtual * p_non_virtual_base);

In the above code, there are two base classes, one declares a virtual method, the other declares a non-virtual function.

Two functions are declared that require pointers to the respective base clases.

The Derived Classes

Let us now test the polymorphism, especially virtual vs. non-virtual (overriding methods). The structures: struct Derived_From_Virtual : public Base_Virtual { void some_virtual_function(); // overrides Base_Virtual::some_virtual_function() };

struct Derived_From_Nonvirtual : public Base_Nonvirtual { void some_function(); }

According to the C++ language, I can pass a pointer to a Derived_From_Virtual to Function_A because Derived_From_Virtual inherits from Base_Virtual. I can also pass a pointer to Derived_From_Nonvirtual to Function_B.

The Difference Between virtual and overriding

The virtual modifier in Base_Virtual, tells the compiler that Function_A will use Derived_From_Virtual::some_virtual_function() instead of the method in Base_Virtual. This is because the method is virtual, the final definition may reside in a future or derived class. The actual definition says to use the method in the most derived class containing the definition.

When passing a pointer to Derived_From_Nonvirtual to Function_B, the compiler will instruct the function to use the method of the base class, Base_Nonvirtual::some_function(). The some_function() method in the derived class is a separate, unrelated, method from the base class.

The primary difference between virtual and overriding occurs with polymorphism.

Thomas Matthews
A: 

The classic example is that of a paint program where a base Shape class is created with a virtual draw() function. Then each of the shapes (circle, rectangle, triangle, etc) can be created as subclass that each implement their draw() function in the appropriate manner and the core paint program can keep a list of Shapes that will each do the appropriate draw() function even though only a pointer to the base Shape class is stored.

Dave Johansen
A: 

ABSTRACT

In this paper, we discuss virtual functions in C++. Part zero explains how virtual functions are declared and overridden. Part one attempts (and perhaps fails) to explain how virtual functions are implemented. Part two is a sample program that uses the example classes defined in parts zero and one. Part three is the classic animal example given in every virtual function - polymorphism tutorial.

PART ZERO

A method of a class is said to be virtual if and only if its declared to be so.

class my_base
{
public:
            void non_virtual_test() { cout << 4 << endl; } // non-virtual
    virtual void virtual_test()     { cout << 5 << endl; } // virtual
};

(Of course, I am assuming the programmer did not previously do anything like #define virtual.)

A class that redeclares and re-implements a non-virtual method of one of its bases is said to overload that method. A class that redeclares and re-implements a virtual method of one of its bases is said to override that method.

class my_derived : public my_base
{
public:
    void non_virtual_test() { cout << 6 << endl; } // overloaded
    void virtual_test()     { cout << 7 << endl; } // overriden
};

PART ONE

When the compiler detects a class has virtual methods, it automatically adds a virtual method table (also known as vtable) to the class' memory layout. The result is similar to what would have been generated from compiling this code:

class my_base
{
//<vtable>
// The vtable is actually a bunch of member function pointers
protected:
    void (my_base::*virtual_test_ptr)();
//</vtable>

// The actual implementation of the virtual function
// is hidden from the rest of the program.
private:
    void virtual_test_impl() { cout << 5 << endl; }

// Initializing the real_virtual_test pointer in the vtable.
public:
    my_base() : virtual_test_ptr(&my_base::virtual_test_impl) {}

public:
    void non_virtual_test() { cout << 4 << endl; }
    // The interface of the virtual function is a wrapper
    // around the member function pointer.
    inline void virtual_test() { *virtual_test_ptr(); }
};

When the compiler detects a class has overridden a virtual method, it replaces its associated entry in the vtable. The result is similar to what would have been generated from compiling this code:

class my_derived : public my_base
{
// The actual implementation of the virtual function
// is hidden from the rest of the program.
private:
    void virtual_test_impl() { cout << 7 << endl; }

// Initializing the real_virtual_test pointer in the vtable.
public:
    my_derived() : virtual_test_ptr(&my_derived::virtual_test_impl) {}

public:
    void non_virtual_test() { cout << 6 << endl; }
};

PART TWO

Now that it's clear that virtual functions are implemented using vtables, which are nothing but a bunch of function pointers, it should be clear what this code does:

#include <iostream>

using namespace std;

class my_base
{
    public:
            void non_virtual_test() { cout << 4 << endl; }
    virtual void virtual_test()     { cout << 5 << endl; }
};

class my_derived : public my_base
{
public:
    void non_virtual_test() { cout << 6 << endl; }
    void virtual_test()     { cout << 7 << endl; }
}

int main()
{
    my_base* base_obj = new my_derived();

    // This outputs 4, since my_base::non_virtual_test() gets called,
    // not my_derived::non_virtual_test().
    base_obj->non_virtual_test();

    // This outputs 7, since the vtable pointer points to
    // my_derived::virtual_test(), not to my_base::virtual_test().
    base_obj->virtual_test();

    // We shall not forget
    // there was an object that was pointed by base_obj
    // who happily lived in the heap
    // until we killed it.
    delete base_obj;

    return 0;
}

PART THREE

Since no virtual function example is complete without an example with animals...

#include <iostream>

using namespace std;

class animal
{
public:
    virtual void say_something()
    { cout << "I don't know what to say." << endl
           << "Let's assume I can growl." << endl; }

    /* A more sophisticated version would use pure virtual functions:
     *
     * virtual void say_something() = 0;
     */
};

class dog
{
public:
    void say_something() { cout << "Barf, barf..." << endl; }
};

class cat
{
public:
    void say_something() { cout << "Meow, meow..." << endl; }
};

int main()
{
    animal *a1 = new dog(), *a2 = new cat();
    a1->say_something();
    a2->say_something();
    delete a1, a2;
    return 0;
}
Eduardo León
+2  A: 

This is more a follow up on the comments from this answer than an answer by itself.

virtual is a keyword that requests runtime dispatch for the method being declared and at the same time declares the method as one of the overrides (implemented pure virtual methods aside). The method being declared, and any method that shares the exact signature and name in the deriving hierarchy from this class down are overrides. When you call a virtual method through a parent pointer or reference, the runtime will call the most derived override in the hierarchy of the called upon object.

When a method is not virtual, and the same method is defined later on in the hierarchy, you are hiding the parent method. The difference here is that when the method is being called through a base pointer or reference it will be calling the base implementation, while if it is being called in a derived object it will call the derived implementation. This, among other cases, is called hiding because the base and derived functions are unrelated, and having it defined in the derived class will hide the base version from a call:

struct base {
   virtual void override() { std::cout << "base::override" << std::endl; }
   void not_override() { std::cout << "base::not_override" << std::endl; }
};
struct derived : base {
   void override() { std::cout << "derived::override" << std::endl; }
   void not_override() { std::cout << "derived::not_override" << std::endl; }
};
int main() {
   derived d;
   base & b = d;

   b.override();     // derived::override
   b.not_override(); // base::not_override
   d.not_override(); // derived::not_override
}

The difference, and what is wrong in the answer by @erik2red is that overrides are intimately related to virtual functions and imply that there is a runtime dispatch mechanism in place that determines the most derived override to call. The behavior that is shown in the answer and associated to override is actually the behavior when there are no overrides but rather method hiding.

Other issues

The language allows for pure virtual methods with implementation. It does not say anything about what terminology should be used with them, but a pure virtual method will never be considered for runtime dispatch. The reason is that when a classes with pure virtual methods (even if implemented) are considered abstract classes, and you cannot instantiate an object of the class. Once you have a derived class that provides an implementation for that method, that implementation becomes the final override in the hierarchy. The class can now be instantiated, but the pure virtual method will not be called through the runtime dispatch mechanism.

Virtual methods that are not the final override, as well as hided methods can be called if using the fully qualified name. In the case of virtual methods, using the fully qualified name disables the polymorphic dispatch mechanism for the call: d.base::override() will call the base implementation even if there are other overrides in deriving classes.

A method can hide other methods in base classes even if the signatures do not match.

struct base {
   void f() {}
};
struct derived : base {
   void f(int) {}
};
int main() {
   derived d;
   // d.f() // error, derived::f requires an argument, base::f is hidden in this context
}

As with overrides, d.base::f() will call the base version, not because it disables polymorphism --it does not, as the method is not declared virtual it will never have polymorphic behavior-- but because the full qualification tells the compiler where the method is, even if it was hidden by another method in the derived class.

David Rodríguez - dribeas
i dbout about an hour before answer this back, i don't disagree with you, the point is your giving strict sense to 'override' word that maybe comes into sense with you, but not to a programmer beginner. By the way, we shouldn't be involved in this fight here. this isn't helpful for anyone but us (both trying to get satisfied)
erick2red
The term 'override' is defined in the standard (10.3 [class.virtual]/2), and as such has a strict meaning. Beginners (and not beginners) better learn those term with the meaning that the standard provides, because that is both a tool to interpret the standard and a language of communication with other programmers. Reading your comment (involved in this fight) I want to apologize if you found any part of the comments or the answer offensive, that was clearly not my intention.
David Rodríguez - dribeas
I agree here, there is nothing less productive than speaking with someone that attributes another meaning to the words than you do... in the worst case you leave the discussion fully satisfied only to discover later on than they interpreted differently from what you thought... It is thus best, especially for beginners to learn the right term early on, as it's difficult once you have an habit to shed it.
Matthieu M.