Reputation: 4284
In this C++ program,
#include<iostream>
using namespace std;
class Base
{
public:
Base()
{
cout<<"\n\nBase ctr";
fun();
}
virtual void fun()
{
cout<<"\n\nBase's fun()";
}
};
class Derived : public Base
{
public:
Derived()
{
cout<<"\n\nDerived ctr";
fun();
}
virtual void fun()
{
cout<<"\n\nDerived's fun()";
}
};
int main()
{
Derived obj;
return 0;
}
when calling a virtual function from Base class's constructor using Derived class object, Base's class fun() gets called,
output::
Base ctr
Base's fun()
Derived ctr
Derived's fun()
reason in explained here but
in this java program,
class Base
{
Base()
{
System.out.println( "\n\nBase ctr" );
fun();
}
void fun()
{
System.out.println( "\n\nBase's fun()" );
}
}
class Derived extends Base
{
int a=1;
Derived()
{
System.out.println( "\n\nDerived ctr a = "+a );
a=8;
fun();
}
void fun()
{
System.out.println( "\n\nDerived's fun() a = "+a );
}
public static void main(String args[])
{
Derived obj = new Derived();
}
}
output is ::
Base ctr
Derived's fun() a = 0
Derived ctr a = 1
Derived's fun() a = 8
here, Derived class fun() is being called, so the constraint applied to c++ program, is not applicable to JAVA program. why?
Upvotes: 1
Views: 3140
Reputation: 208446
The two languages take a different approach to dynamic dispatch. In C++ it will only dispatch to a fully constructed object. That is handled by changing the type of the object during construction as the different levels of the hierarchy constructor start executing. Java on the other hand, considers the object to be of the most derived type before even starting the base-most constructor.
The problem with the Java approach is that it might actually be executing code on an object that has not yet been constructed. Consider that the derived type had a field initialized to X, and that it is accessed/updated in a method. Calling that method on the base object would access the member before the constructor has initialized it.
At any rate, you should avoid calling a virtual function in the constructor or destructor of your object in either language.
Illustrative example:
public class Base {
public final int x;
public Base() {
x = foo();
}
int foo() { return 1; }
}
public class Derived extends Base {
public final int y;
public Derived() {
y = 2;
}
int foo() { return y; }
}
Derived d = new Derived();
assert( d.x == d.y ); // Can this ever fail?
In this code, we have 2 final int
, and the code seems simple enough to reason about. Can the assert
ever fail?
Upvotes: 3