Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling virtual method in base class constructor

I know that calling a virtual method from a base class constructor can be dangerous since the child class might not be in a valid state. (at least in C#)

My question is what if the virtual method is the one who initializes the state of the object ? Is it good practice or should it be a two step process, first to create the object and then to load the state ?

First option: (using the constructor to initialize the state)

public class BaseObject {     public BaseObject(XElement definition) {         this.LoadState(definition);     }      protected abstract LoadState(XElement definition); } 

Second option: (using a two step process)

public class BaseObject {     public void LoadState(XElement definition) {         this.LoadStateCore(definition);     }      protected abstract LoadStateCore(XElement definition); } 

In the first method the consumer of the code can create and initialize the object with one statement:

// The base class will call the virtual method to load the state. ChildObject o = new ChildObject(definition) 

In the second method the consumer will have to create the object and then load the state:

ChildObject o = new ChildObject(); o.LoadState(definition); 
like image 650
Yona Avatar asked Jan 15 '09 20:01

Yona


People also ask

Can we call virtual method from constructor?

Calling virtual methods in constructor/destructor in C++You can call a virtual function in a constructor. The Objects are constructed from the base up, “base before derived”.

Can a virtual function be called in a base class?

A virtual function is a member function that you expect to be redefined in derived classes. When you refer to a derived class object using a pointer or a reference to the base class, you can call a virtual function for that object and execute the derived class's version of the function.

Why should calls to virtual functions be avoided in constructors and destructors?

So, Don't invoke virtual functions from constructors or destructors that attempts to call into the object under construction or destruction, Because the order of construction starts from base to derived and the order of destructors starts from derived to base class.

Can we declare base class constructor as virtual?

Virtual Constructor in C++ In C++, the constructor cannot be virtual, because when a constructor of a class is executed there is no virtual table in the memory, means no virtual pointer defined yet. So, the constructor should always be non-virtual. But virtual destructor is possible.


1 Answers

(This answer applies to C# and Java. I believe C++ works differently on this matter.)

Calling a virtual method in a constructor is indeed dangerous, but sometimes it can end up with the cleanest code.

I would try to avoid it where possible, but without bending the design hugely. (For instance, the "initialize later" option prohibits immutability.) If you do use a virtual method in the constructor, document it very strongly. So long as everyone involved is aware of what it's doing, it shouldn't cause too many problems. I would try to limit the visibility though, as you've done in your first example.

EDIT: One thing which is important here is that there's a difference between C# and Java in order of initialization. If you have a class such as:

public class Child : Parent {     private int foo = 10;      protected override void ShowFoo()     {         Console.WriteLine(foo);     } } 

where the Parent constructor calls ShowFoo, in C# it will display 10. The equivalent program in Java would display 0.

like image 184
Jon Skeet Avatar answered Sep 22 '22 13:09

Jon Skeet