El problema con Instrument2.cpp puede verse al ejecutar el programa. La salida es Instrument::play. Claramente, ésta no es la salida deseada, porque se sabe que el objeto es en realidad un Wind y no sólo un Instrument. La llamada debería producir un Wind::play. Del mismo modo, para cualquier objeto de una clase que derive de la clase Instrument debería usarse su propia versión de play(), independientemente de la situación.
El comportamiento de Instrument2.cpp no es sorprendente dado el enfoque de C respecto a las funciones. Para entender el resultado es necesario comprender el concepto de binding (ligadura).
Conectar una llamada a una función al cuerpo de la función se conoce como binding (ligadura). Cuando la ligadura se realiza antes de ejecutar el programa (por el compilador y el enlazador), se la conoce como early binding (ligadura temprana). Puede que no haya oído antes este término porque nunca ha sido una opción en los lenguajes procedurales: los compiladores de C sólo tienen un tipo de llamada a función, que es la ligadura temprana.
El problema en el programa anterior está causado por la ligadura temprana, porque el compilador no puede saber cuál es la función correcta a la que llamar cuando sólo tiene una dirección de Instrument.
La solución se conoce como ligadura tardía (late binding), que significa que la ligadura se produce en tiempo de ejecución basándose en el tipo de objeto. También es conocida como ligadura dinámica o ligadura en tiempo de ejecución. Cuando un lenguaje implementa la ligadura dinámica debe existir algún tipo de mecanismo para determinar el tipo del objeto en tiempo de ejecución y llamar a la función miembro apropiada. En el caso de un lenguaje compilado, el compilador sigue sin conocer el tipo real del objeto, pero inserta código que lo averigua y llama al cuerpo correcto de la función. El mecanismo de la ligadura dinámica varía de un lenguaje a otro, pero se puede imaginar que algún tipo de información debe ser introducida en los objetos. Más adelante se verá cómo funciona.