8

Una libreria fornisce una classe con funzioni virtuali. Questa classe può essere estesa con nuove funzioni virtuali senza ricompilare i binari collegati dinamicamente alla libreria?È possibile estendere un'interfaccia virtuale senza ricompilazione del codice client?

Credo che questo non sia possibile in standard. Ci sono piattaforme che consentono questo?

Sarebbe più semplice se nuove funzioni venissero aggiunte alla fine del corpo della classe?

+0

Desidero estendere l'interfaccia della libreria. Se esiste un altro modo per ottenere ciò senza modificare le firme delle funzioni API accettando la classe della libreria principale come argomento, mi piacerebbe saperlo anche io. – Basilevs

+1

c'è un documento interessante del progetto KDE: [Problemi di compatibilità binaria con C++] (http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B). Link a due altri documenti che potresti essere interessato a leggere. – Mat

risposta

5

Lo standard non riguarda la compatibilità binaria. Riguarda però le classi e "cambiando" la definizione di una classe da una unità di traduzione a un'altra effettivamente invocate un comportamento indefinito.

La maggior parte dei compilatori consente una serie di modifiche senza la necessità di ricompilazione, tuttavia l'elenco è piccolo ... e per questo direi che potrebbe non essere possibile, a seconda della conoscenza a priori del derivato classi.

Il problema che presumo risiede nell'ottimizzazione che i compilatori normalmente eseguono sui tavoli virtuali.

Quando si crea una classe con funzioni virtuali, si ottiene una tabella virtuale che assomiglia così:

// B virtual table 
0 - Offset to complete object 
1 - RTTI 
2 - func0 
3 - func1 
... 

Al fine di guadagnare un po 'di spazio, la classe derivata proprie funzioni virtuali sono di solito "aggiunto":

// D virtual table 
Same as B 
N+3 - func(N+1) 
N+4 - func(N+2) 

questo modo un oggetto D ha soltanto un puntatore virtuale, che può essere usata come tale anche quando il tipo è (staticamente) un B (tramite puntatore o un riferimento).

Tuttavia, se si dovesse estendere B senza ricompilare D, allora sarebbe incidente semplicemente, dal momento che quando si chiama la funzione N+1 di B si sarebbe invece chiamare la funzione di DN+1 che probabilmente non hanno nemmeno gli stessi argomenti. .. oups!

Si può fare, tuttavia, se si utilizza che nessuna classe derivata aggiunga alcuna funzione virtuale propria.

+2

Nota che alcune librerie aggiungono un paio di funzioni virtuali fittizie alla fine (di solito chiamate 'reserved1',' reserved2' ecc.) In modo che possano essere successivamente sostituite senza rompere la compatibilità binaria. –

+0

@Jan Hudec: intelligente :) Mi fa pensare a pezzi di ricambio ^^ –

+0

Come dici tu, lo standard C++ non include la compatibilità ABI. Di fatto, non impone nemmeno l'uso di un vtable per l'invio dinamico. È solo un dettaglio di implementazione che la maggior parte dei compilatori (tutti?) Utilizzano. – rjnilsson