views:

63

answers:

2
#include <iostream> 
using namespace std;  

class base  
{  
public:  
    void f() {cout << "base" << endl;}  
    virtual void v() {cout << "base (virtual)" << endl;}  


};  

class deriv : public base  
{  
public:  
    void f() {cout << "deriv" << endl;}  
    void v() {cout << "deriv (overridden)" << endl;}  
};  


int main()  
{  
    base b;  
    b.f();  
    b.v();  

    deriv d;  
    d.f();  
    d.v();  
}

I don't understand what real difference is there between those two methods f and v: if I replace a function with another with the same name, am I not "replacing" it ? Even if I can still access it by creating a base* pointer and then make it point to a deriv object, I don't understand what kind of "clean" use of C++ there is here.

When not using virtual (meaning overriddable methods) methods, can somebody tell me if there is a legitimate use for this, and what is different from using overridden virtual method ?

EDIT: I'm sorry using bad syntax with markdown, but markdown is a really bad choice, it's complicated and quite capricious (I prefer textile hehe). EDIT2: Sorry I didn't guess 101010101010101 button meant to insert code, I usually just do it by hand :(

+6  A: 

The point is to get polymorphic behavior. If a function in a base-class is declared virtual, and a derived class overrides it, if you call the function using a base class pointer it will automatically call the function in the derived class. If it's not virtual, then it will call the base-class function.

The basic idea is so you can do things like this:

class Animal
{
    public:
    virtual void talk() = 0;
};

class Dog : public Animal
{
    public:
    void talk() { cout << "Bark" << endl; }
};

class Cat : public Animal
{
    public:
    void talk() { cout << "Meow" << endl; }
};

void foo(Animal* a)
{
    a->talk();
}

Now when you pass an Animal pointer to foo() and invoke the talk() member function, it will do something different depending on whether it points to a Cat object or a Dog object. The point is that foo() is able to work with anything that inherits from Animal. Plus, if some time later you create a new kind of Animal class, you can pass it to foo() with no problem and without having to modify any code inside foo().

Charles Salvia
+3  A: 

You'll only see the difference between the two when you're using a pointer or reference.

deriv * d = new deriv;
d->f(); // "deriv"
d->v(); // "deriv (overridden)"

As expected. Now we cast this pointer to a base pointer:

base * b = static_cast<base *>(d);
b->f(); // "base"
b->v(); // "deriv (overridden)"

The virtual function call goes to the derived function, even though the pointer is a pointer to the base class.

Mark Ransom
Just for completeness, references have the same effect.
doron
@doron, I said that in the first sentence. Granted it was easy to miss.
Mark Ransom