1. Descripción del problema
En el sistema de herencia, si la clase derivada quiere usar el constructor de la clase base, debe declararlo explícitamente en su constructor.
Por ejemplo:
Aquí, B deriva de A, y B
también llama al constructor de A en su constructor. Así se completa la transferencia del constructor.
Otro ejemplo: cuando B contiene una variable miembro:
Ahora, la estructura B derivada de A incluye una variable miembro. Inicializamos la clase base A y, al mismo tiempo, también inicializamos el miembro d. El problema es: si la clase base tiene numerosas versiones diferentes de constructores, entonces, siguiendo el razonamiento anterior, en la clase derivada todavía hay que escribir muchos constructores de “reenvío” correspondientes. Por ejemplo:
Obviamente, cuando hay muchos constructores en la clase base, la escritura de los constructores de la clase derivada se vuelve muy redundante y bastante incómoda.
2. Solución del problema
Podemos simplificar este problema mediante la declaración using; veamos un ejemplo:
En el código, tanto la clase base como la derivada declaran una función f con el mismo nombre. Pero el método en la clase derivada tiene una versión diferente de la de la clase base. Aquí se usa la declaración using para indicar que la clase derivada también usa la versión de la función f de la clase base. Así, la clase derivada tiene dos versiones de la función f. Cabe señalar que si no se usa la declaración using para heredar la función homónima de la clase base, entonces la función f definida en la clase derivada ocultará la función f de la clase base; por supuesto, si la clase derivada no define la función homónima f, seguirá eligiendo la función f de la clase base.
Este método también se puede trasladar a la herencia de constructores. Es decir, la clase derivada puede declarar mediante la sentencia using que hereda todos los constructores de la clase base en la subclase. Por ejemplo:
Ahora, mediante la declaración `using A::A`, todos los constructores de la clase base se heredan a la clase derivada. Lo más ingenioso es que esta herencia se declara implícitamente. Es decir, si un constructor heredado no es utilizado por el código relevante, el compilador no generará código de función real para él; así se ahorra más espacio de código objeto que reenviar directamente varios constructores de la clase base. Pero en este momento hay otro problema:
Cuando se usa la sentencia using para heredar constructores de la clase base, la clase derivada no puede inicializar los nuevos miembros de clase definidos por la propia clase. Podemos usar la expresión de inicialización de miembros de clase para establecer un valor inicial predeterminado para los miembros de la clase derivada. Por ejemplo:
Nota:
1. Para los constructores heredados, los valores predeterminados de los parámetros no se heredan; además, los valores predeterminados hacen que la clase base genere múltiples versiones de constructores (es decir, los parámetros se reducen de atrás hacia adelante hasta incluir el constructor sin parámetros; por supuesto, si es el constructor de copia predeterminado, también se incluye). Todas estas versiones de funciones serán heredadas por la clase derivada.
2. Manejo de conflictos en constructores heredados: cuando la clase derivada tiene múltiples clases base, algunos constructores de las múltiples clases base pueden hacer que el nombre de función de los constructores heredados en la clase derivada sea el mismo.
Los parámetros también son iguales; entonces los constructores heredados en la clase derivada darán lugar a código no válido de la clase derivada, por ejemplo:
Aquí se producirá un conflicto entre los constructores heredados en la clase derivada. Una solución es heredar explícitamente los constructores conflictivos de la clase base, impidiendo así la generación implícita de los constructores heredados correspondientes, para evitar el conflicto.
3. Si el constructor de la clase base se declara como constructor privado, o si la clase derivada hereda virtualmente de la clase base, entonces no se pueden declarar constructores heredados en la clase derivada.
4. Una vez que se usan constructores heredados, el compilador no generará un constructor predeterminado para la clase derivada. Por lo tanto, debemos prestar atención a si la versión sin parámetros del constructor heredado es necesaria.
Fuente: http://www.cnblogs.com/yangykaifa/p/6737354.html