La jerarquía de las llamadas a los constructores plantea un interesante dilema. ¿Qué ocurre si se está dentro de un constructor y se llama a una función virtual? Dentro de una función miembro ordinaria se puede imaginar que ocurrirá - la llamada virtual es resuelta en tiempo de ejecución porque el objeto no puede conocer si la función miembro es de la clase en la que está o es de una clase derivada. Por consistencia, se podría pensar que también es lo que debería ocurrir dentro de los constructores.
No es el caso. Si se llama a una función virtual dentro de un constructor, sólo se usa la versión local de la función. Es decir, el mecanismo virtual no funciona dentro del constructor.
éste comportamiento tiene sentido por dos motivos. Conceptualmente, el trabajo del constructor es dar al objeto una existencia. Dentro de cualquier constructor, el objeto puede ser formado sólo parcialmente - se puede saber sólo que los objetos de la clase base han sido inicializados, pero no se puede saber que clases heredan de ésta. Una función virtual, sin embargo, se mueve "arriba" y "abajo" dentro de la jerarquía de herencia. Llama a una función de una clase derivada. Si se pudiera hacer esto dentro de un constructor, se estaría llamando a una función que debe manejar miembros que todavía no han sido inicializados, una receta segura para el desastre.
El segundo motivo es mecánico. Cuando se llama a un constructor, una de las primeras cosas que hace es inicializar su VPTR. Sin embargo, sólo puede saber que es del tipo "actual" - el tipo para el que se ha escrito el constructor. El código del constructor ignora completamente si el objeto está en la base de otra clase. Cuando el compilador genera código para ese constructor, se genera código para un constructor de esa clase, no para la clase base, ni para una clase derivada (debido a que una clase no puede saber quién la hereda). Por eso, el VPTR que use debe apuntar a la VTABLE de esa clase. El VPTR permanece inicializado a la VTABLE para el resto de vida del objeto a menos que no sea la última llamada al constructor. Si posteriormente se llama a un constructor de una clase derivada, éste constructor pone el VPTR a su VTABLE, y así hasta que el último constructor termine. El estado del VPTR es determinado por el constructor que sea llamado en último lugar. Otra razón por la que los constructores son llamados en orden desde la base al más derivado.
Pero mientras que toda esta serie de llamadas al constructor tiene lugar, cada constructor ha puesto el VPTR a su propia VTABLE. Si se usa el mecanismo virtual para llamar a funciones, producirá sólo una llamada a través de su propia VTABLE, y no de la VTABLE del más derivado (como debería suceder después de que todos los constructores hayan sido llamados). Además, muchos compiladores reconocen cuando se hace una llamada a una función virtual dentro de un constructor, y realizan una ligadura estática porque saben que la ligadura dinámica producirá una llamada a una función local. En todo caso, no se conseguirán los resultados que se podían esperar inicialmente de la llamada a una función virtual dentro de un constructor.