2012-02-08 9 views
6

Vamos a empezar desde fragmento de código:gcc 4.5.1 tema herencia virtual

#include <iostream> 

struct God{ 
    God(){_test = 8;} 
    virtual ~God(){} 
    int _test; 
}; 

struct Base1 : public virtual God{ 
    //Base1(){std::cout << "Base1::Base1" << std::endl;} //enable this line to fix problem 
    virtual ~Base1(){} 
}; 

struct Base2 : public virtual Base1{ 
    virtual ~Base2(){} 
}; 

struct A1 : public virtual Base2{ 
    A1(){std::cout << "A1:A1()" << std::endl;} 
    virtual ~A1(){}; 
}; 

struct A2 : public virtual Base2{ 
    A2(){std::cout << "A2:A2()" << std::endl;} 
    virtual ~A2(){}; 
}; 


struct Derived: public virtual A1, public virtual A2{ 
    Derived():Base1(){std::cout << "Derived::Derived()" << std::endl;} 
    Derived(int i){std::cout << "Derived(i)::Derived(i)" << std::endl;}   
    virtual ~Derived(){} 
}; 


int main(){ 

    God* b1 = new Derived(); 
    std::cout << b1->_test << std::endl; //why it prints 0? 

    God* b2 = new Derived(5); 
    std::cout << b2->_test << std::endl; 

    return 0; 
} 

compilado con GCC 4.5.1 y 4.6.1 La única diferencia entre los constructores de clase derivada es que primero establece explícitamente qué Base1 constructor debe ser llamado. Esperaría que tanto cout en main() imprima 8. Lamentablemente, el primero imprime 0 !.

¿Por qué?

Si habilito definición explícita de Base1 constructor se soluciona el problema. Si elimino la herencia virtual en la definición de clase Derivada (clase derivada: pública A1, pública A2), también funciona. ¿Se espera un comportamiento?

La cuestión no es observable bajo GCC 3.4.4 o Microsoft compilador (VS)

+0

Me sale "8" con gcc 3.4.6 – Beta

+0

Ciertamente parece que me has activado un error de gcc. –

Respuesta

1

esto debe ser un error del compilador. También probé GCC 4.2.1 y el resultado es 8 en ambos casos.

1

He probado con varios sabores antiguos (hasta 4.3 - que funciona) - no tengo una serie 4.4 a mano (lo probaré por la mañana), pero estoy de acuerdo, esto parece ser un error (y no en el db), probablemente valga la pena subirlo.

Me he dado cuenta de que si cambia la primera relación (Base1 a Base1 a God de virtual a no virtual), entonces el ejemplo funciona como se esperaba. Supongo que esto depende de sus necesidades, ya sea que llame directamente al codificador de God desde la clase más derivada (aunque nunca he visto este enfoque antes ...)

Cuestiones relacionadas