2010-07-10 20 views
9

tengo una clase base que declara y define un constructor, pero por alguna razón mi derivada públicamente clase no está viendo que el constructor, y por lo tanto tengo que declarar explícitamente un constructor de reenvío en la clase derivada:¿Por qué mi subclase de C++ necesita un constructor explícito?

class WireCount0 { 
protected: 
    int m; 
public: 
    WireCount0(const int& rhs) { m = rhs; } 
}; 

class WireCount1 : public WireCount0 {}; 

class WireCount2 : public WireCount0 { 
public: 
    WireCount2(const int& rhs) : WireCount0(rhs) {} 
}; 

int dummy(int argc, char* argv[]) { 
    WireCount0 wireCount0(100); 
    WireCount1 wireCount1(100); 
    WireCount2 wireCount2(100); 
    return 0; 
} 

En el código anterior, el compilador rechaza mi declaración WireCount1 wireCount1(100) ("No hay función de coincidencia para la llamada a 'WireCount1 :: WireCount1 (int)'"), mientras que mis declaraciones wireCount0 y wireCount2 están bien.

No estoy seguro de entender por qué necesito proporcionar el constructor explícito que se muestra en WireCount2. ¿Es porque el compilador genera un constructor predeterminado para WireCount1, y ese constructor oculta el constructor WireCount0?

Como referencia, el compilador es i686-apple-darwin10-gcc-4.2.1 (GCC) 4.2.1 (Apple Inc. build 5659).

Respuesta

4

Todas las clases derivadas deben llamar al constructor de su clase base en alguna forma o forma.

Cuando crea un constructor sobrecargado, el compilador predeterminado genera el constructor sin parámetros desaparece y las clases derivadas deben llamar al constructor sobrecargado.

Cuando se tiene algo como esto:

class Class0 { 
} 

class Class1 : public Class0 { 
} 

El compilador genera esta realidad:

class Class0 { 
public: 
    Class0(){} 
} 

class Class1 : public Class0 { 
    Class1() : Class0(){} 
} 

Cuando se tiene el constructor no predeterminado, ya no se genera el constructor sin parámetros. Cuando se define la siguiente:

class Class0 { 
public: 
    Class0(int param){} 
} 

class Class1 : public Class0 { 
} 

El compilador ya no genera un constructor en la Clase 1 para llamar al constructor de la clase base, debe hacerlo explícitamente que usted mismo.

+0

Creo que leyó mal su pregunta. No está preguntando por qué no puede llamar al constructor predeterminado de Class1, sino más bien por qué no hay un constructor Class1 (int) para llamar. – Shirik

+1

El compilador aún genera un constructor 'Class1()' en su último ejemplo. Es solo que este constructor está mal formado si está realmente definido (de manera predeterminada como para todas las funciones especiales, solo se declara hasta que realmente se usa).Puede verificar esto haciéndolo amigo: 'clase Class2 {friend Class1 :: Class1(); }; ', que funciona porque el compilador declara implícitamente el constructor predeterminado sin importar si realmente se podría llamar. –

+0

Gracias. Eso me lo deja muy claro. Aunque aprecio la respuesta de Shirik, creo que su ejemplo muestra exactamente lo que ha estado sucediendo en mi código. –

14

Los constructores no se heredan. Debes crear un constructor para la clase derivada. El constructor de la clase derivada, además, debe llamar al constructor de la clase base.

+1

Además, si la clase base tiene un constructor predeterminado, el compilador usará ese si no especifica explícitamente un constructor en la lista de inicializadores de un constructor en la clase derivada. –

+0

Gracias. No me di cuenta de que los constructores nunca fueron heredados. Me había convencido de que otros constructores de la clase base (en el código real) eran de hecho visibles, pero ahora lo atribuyo a un montón de castings que el compilador pudo haber estado haciendo. –

+0

Lamento que, como novato, todavía no tengo suficientes puntos de reputación para aumentar tu respuesta. –

1

Tienes que construir tu clase base antes de tratar con derivados. Si construye su clase derivada con constructores no triviales, el compilador no puede decidir a qué llamar para base, por eso ocurre un error.

+0

Otra respuesta más correcta. Gracias. –

Cuestiones relacionadas