Friday, May 8, 2009

Virtual Function Calls from Constructors/Finalizers … Bad Idea!

So I am skimming over this book, Framework Design Guidelines by Krzysztof Cwalina and Brad Abrams, when authors note to “avoid calling virtual members on an object inside its constructor”. At first a developer might not think about the danger but it does make sense with a quick example that authors provide.

Here is another one i cooked up:

public class Trans {
public abstract Log();
public Trans() {
Log(...);
}
}

public class SomeTrans:Trans {
private Logger logger;
public SomeTrans() {
logger = new Logger();
}
public override Log(...) {
if (logger == null)
Console.Write("Oops!");
else
logger.write(...);
}
}

Using the base class to execute common code that all derived classes will might seem like a good idea but here the Trans constructor calls the derived type’s Log method before SomeTrans constructor is called. Compiler is unable to detect this danger because binding happens at run-time so be very aware.

The rule of thumb is to never do that!

Also note, C++ behaves differently as it does not allow a virtual traversal because at base construction time the object type is Trans.

No comments: