Reputation: 6633
#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 :(
Upvotes: 2
Views: 463
Reputation: 308111
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.
Upvotes: 4
Reputation: 53289
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()
.
Upvotes: 6