2011-07-19 8 views

Respuesta

3

¿Qué significa para mantener la compatibilidad binaria para usted?

La disposición objeto será el mismo, pero se le rompe la regla de un Definición a menos que vuelva a compilar todo el código, momento en el que la compatibilidad binaria es básicamente inútil. Sin recompilar, entonces la ODR está rota, y aunque podría ser el caso de que funcione, es posible que tampoco funcione.

En particular, si todos los métodos virtuales en la clase son puros o definidos en línea, entonces el compilador puede generar el vtable en cada unidad de traducción que incluye el encabezado y marcarlo como un símbolo débil. Luego el enlazador seleccionará uno de ellos y descartará todos los demás. En esta situación no se requiere que el enlazador para verificar que todos los vtables son exactamente los mismos y seleccionará una de forma aleatoria (o de forma determinista de manera indefinida), y podría recoger uno de esos vtable donde el método es virtual pura, que a su turn puede terminar bloqueando la aplicación si se llama al método en un objeto de la clase base.

+0

En mi caso, no todos los métodos virtuales son puros, hay una mezcla. Sin embargo, creo que reconstruiré todo de todos modos, en lugar de vivir con la incertidumbre. –

+0

Específicamente tenía N bibliotecas compartidas.Solo llamo a la función virtual a través de un puntero de clase base en la primera lib; las otras bibliotecas N-1 contienen clases derivadas con re-implementaciones de esa función. Planeé cambiar lo puro a lo no puro y recompilar la primera biblioteca solamente. –

4

Hay emite ninguna compatibilidad cuando se cambia de pura virtual a virtual y luego volver a compilar el código. (Sin embargo, virtual a pura virtual puede causar problemas.)

La única cosa que usted debe tener cuidado es que los no puros virtual métodos deben tener un cuerpo. No pueden permanecer sin implementar. es decir,

class A { 
public: 
    virtual int foo() 
    { 
    return 0; //put some content 
    } 
}; 

No se puede simplemente poner como,

virtual int foo(); 

Esto causará error de vinculador, incluso si no lo utiliza.

+0

esto no es realmente segura, esto es una violación de la ODR (diferentes unidades de traducción tienen diferentes definiciones para el mismo tipo) y podría causar problemas en algunas circunstancias. –

+0

@David, ¿puedes dar un ejemplo? – iammilind

+0

Creo que proporcioné la respuesta que di, pero intentaré simplificar. Si todos los métodos virtuales son puramente virtuales o están definidos en línea en la definición de la clase, entonces no existe una única unidad de traducción que cree el vtable, sino todas las traducciones que incluyen dicho encabezado. El vtable se marcará como un símbolo débil y el vinculador * elegirá * aleatoriamente uno de ellos. Si tiene código que depende de la clase base instanciable ser que llama al (no pura para esta unidad de traducción) función virtual, y el enlazador ha elegido un vtable donde esa función es puro ... –

Cuestiones relacionadas