views:

122

answers:

5

Possible Duplicate:
Why do we not have a virtual constructor?

I know this has been asked before but I didn't understand the complex technical words used in the other answers.

I read on a community the reason that constructors cannot be virtual is

The ‘virtual’ mechanism works on a logically complete (completely constructed) object. We know that we use constructors to logically initialize our objects. In other words, the object is not completely constructed until the constructor has finished executing. Thus, we can’t have virtual constructors.

There is a misconception that by then virtual table is incomplete so we can’t have virtual constructors. Just before the constructor starts executing the virtual table is properly constructed and the ‘this’ pointer passed to the constructors. Moreover, virtual table mechanism is implementation depended, and finds no place in the C++ standard. And hence, to argue over this issue using the virtual table concept is illogical.

Now, as the constructor finishes executing any other function can be virtual. Destructor is no exception to this rule as it is a function. Virtual destructors are required in case we use a base class pointer to refer to a derived class object, use it, and then delete it. If we have virtual destructor, using ‘delete’, a chain of destructors is called starting from the derived to the base. But, had there been no ‘virtual’ in destructor only the base class destructor is called (and not the derived). This (may) generate inconsistencies in the program.

Is the above reason correct? The answer doesn't talk about the static and dynamic types of objects.

A: 

Yes, the reason is you need to have a pointer/reference to a complete object already before you can call a virtual function. When the constructor is being invoked there's no complete object yet. Even more, when you do new SomeClass() you don't even have a pointer yet - the pointer is returned upon the new statement is completed successfully.

sharptooth
+5  A: 

Virtual constructors don't make sense and aren't necessary. The only time you call a constructor is when creating an object. You need to know the type of an object in order to create it, so the static and dynamic types are the same, and the correct constructor to call is the one for that type.

That's why they aren't necessary. Why they don't make sense, is that when creating an object, base class constructors are called as well as derived class constructors. If the base class constructor was overridden in the derived class, is that supposed to mean that the base class constructor isn't called after all?

Other languages have virtual constructors, perhaps because constructors in those languages are methods, and they only have virtual invocation for non-static methods. But those other languages (Java and Python spring to mind) have to introduce special rules that constructors must/should construct their base class explicitly as a call from the constructor. C++ just does it (perhaps in an initializer list, if the base class constructor requires parameters), using non-virtual constructors, and there is no option to enter the body of the constructor with uninitialized base class sub objects.

Steve Jessop
But algebraic types in functional programming use the equivalent of virtual constructors all the time (just have a look at the `Maybe` monad), and there exists a (convoluted) solution via factory methods to implement this in languages that don’t support them. So I’d say that they make sense and are necessary.
Konrad Rudolph
@Konrad: I can't comment on functional languages, whether their model of a constructor is similar enough to C++'s model of a constructor, that the same analysis applies. As far as virtual factory methods go, it's *occasionally* useful for a class to have the virtual constructor idiom `clone` and `create` non-static member functions, in addition to regular constructors. I don't think it's necessary to build that into every object, although Java's use of the `Cloneable` interface as a flag to enable it is fairly nifty.Not sure if CRTP can achieve the same in C++ without convolution...
Steve Jessop
@Steve: you must be the last person to describe `Cloneable` as nifty – everyone else has reached the consensus that this interface is a [complete](http://stackoverflow.com/questions/709380/java-rationale-of-the-cloneable-interface/709438#709438) and utter [disaster](http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4098033), and to use [other solutions](http://www.artima.com/intv/bloch13.html) instead.
Konrad Rudolph
@Konrad: I said "nifty", not "perfect" ;-p The nifty part is just that you use the interface to mark the class for copying by the VM. The fact that `clone` is a protected method of `Object` is not nifty. If Java had mixins, `Cloneable` would be one, would provide a public default implementation of `clone`, and then would basically just work (although perhaps should have separate deep_clone and shallow_clone interfaces). But apparently multiple inheritance is evil, so Java sleeps in the bed it made...
Steve Jessop
+2  A: 

The virtual keyword cannot be applied to a constructor since a constructor turns raw bits into a living object, and until there is a living object against which to invoke a member function, the member function cannot possibly work correctly. Instead of thinking of constructors as normal member functions on the object, imagine that they are static member functions that create objects. - C++ FAQs

Prabhu Jayaraman
+2  A: 

To quote from The C++ Programming Language:

To construct an object, a constructor needs the exact type of the object it is to create. Consequently, a constructor cannot be virtual. Furthermore, a constructor is not quite an ordinary function. In particular, it interacts with memory management routines in ways ordinary member functions don’t. Consequently, you cannot have a pointer to a constructor.

It must be interesting to note that C++ do have an idiom called virtual constructor. You can read more about that here.

Vijay Mathew
A: 

Link to Bjarne's take on this.

Chubsdad