Monday, May 21, 2007

Comparisons of C++ and Java (III): Method Overriding

Method overriding is not quite the same in C++ as in Java. Here are some examples show the differences:

Method overriding in Java

base.java

public class base {
base (){}
void printMsg(){
System.out.println("print from base class");
}
}

Derived.java

public class derived extends base {
derived (){}
void printMsg(){
System.out.println("print from derived class");
}
}

test code snippet:


public static void main(String args[]){
base b = new derived();
b.printMsg();
}

What do we get:

>> print from derived class

Non-virtual method overriding in C++

base.h

class base{
public:
base(){}
void printMsg();
};

base.cc
void base::printMsg(){
cout<<" print from base"<<endl;
}

derived.h
class derived : public base {
public:
derived(){};
void printMsg();
};

derived.cc

void derived::printMsg(){
cout<<" print from derived class"<<endl;
}

test code snippet:

base* d = new derived();
d->printMsg();

And what do I get:

>>print from base class

which is not what I expect? But how does it happen? The reason is still because of the binding mechanisms in C++ and Java.

As we know there are two binding mechanisms in C++: static binding and dynamic binding. Dynamic binding is implemented through virtual functions; the actual code for the functions is not attached or bound until execution time.

On the other hand, static binding occurs when the functions code is “bound” at compile time. This means that when a non-virtual function is called, the compiler determines at compile time which version of the function to call. When overriding a non-virtual method in a derived class, if we call the method via base class reference or pointer type, the method in the base class is called. In our example above, the printMsg() in the base class is called and print out "print from base class".

As we have discussed before, in Java all method are treated as virtual, so dynamic binding applied all the time. And when we override a method in a derived class, we are able to call the method via a base class reference.

So what is the solution in C++ if I want to call the overridden methods in a derived class via a base class reference?

The answer is to make the method in base class virtual, as shown below:

base.h

class base{
public:
base(){}
virtual void printMsg();
};

Because the function printMsg() is virtual, dynamic binding applies. When we call the derived method via a base class reference, we get what we want:

>> print from derived class

No comments: