2010-10-11 15 views
19

Non è chiaro cosa succede se elimino un metodo virtuale in C++ 0x:eliminazione di funzioni virtuali in C++ 0x

virtual int derive_func() = delete; 

Questo significa questa classe e tutto ciò che eredita da essa non può definire/implementare il metodo derive_func()? O è questo errore illegale/compilato?

+1

@GMan Sono d'accordo che probabilmente non c'è motivo sano di mente, ma la proposta sembra consentire esplicitamente esso. – flownt

+0

@flownt: Oops, mi dispiace. :) Cancellato su di te. – GManNickG

+2

Obbliga la creazione di RTTI. L'equivalente nel C++ corrente è di avere un distruttore virtuale vuoto? –

risposta

14

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2326.html#delete A deleted virtual function may not override a non-deleted virtual function and vice-versa. cioè la sua abbastanza inutile (come ho letto almeno) l'unico uso valida potrebbe essere:

struct A{ 
    virtual void b() = delete; 
}; 
struct B:A{ 
    virtual void b() = delete; 
}; 

che è del tutto inutile, dal momento che la funzione non può mai essere chiamato. per le funzioni non virtuali l'uso è più giustificato

EDIT per essere completamente chiaro questa è l'unica relazione possibile, i bambini non possono implementare e non si può eliminare un virtuale ereditato non cancellato.

+1

Strano. Forse costringe i metodi a essere obsoleti? ma ancora ... –

+1

forza le informazioni RTTI da memorizzare? – KitsuneYMG

+0

Quindi è come la mia risposta cancellata? – Klaim

4

flownt got it right, ma voglio sottolineare che nella finale di C++ 11 progetto (N3337), la lingua corrispondente si è spostato alla sezione 10.3 # 16:

Una funzione con una definizione eliminata non deve sostituisci una funzione che non ha una definizione cancellata. Allo stesso modo, una funzione che non ha una definizione cancellata non sostituisce una funzione con una definizione cancellata. 2

sembra abbastanza chiaro mi (sezione 8.4.3 # 1) che una cancellato definizione in effetti conta come definizione, e di fatto una definizione di linea, il che significa una definizione soddisfa eliminati 10.3 # 11:

una funzione virtuale dichiarato in una classe è definita, o dichiarata puro in quella classe, o entrambi; ma non è richiesta alcuna diagnosi. 2

Tuttavia, sembra che le implementazioni attuali non sono d'accordo. Ecco il mio banco di prova:

struct Base { 
    virtual void bar(); 
    virtual void foo() = delete; 
}; 

void Base::bar() { } // a definition of the first non-inline virtual function 
int main() { Base b; } 
  • Clang produce un programma unlinkable: Base::foo è menzionato nella vtable per Base. E se si scambia l'ordine di foo e bar, il linker lamenta che l'intero vtable non è presente (perché Clang pensa foo è una funzione non in linea con nessuna definizione). I filed this as a bug; vedremo cosa pensano gli sviluppatori.

  • GCC lamenta un "utilizzo" di foo alla fine dell'unità di traduzione, quando crea il vtable; ma non identificare correttamente bar come prima funzione membro virtual non in linea, non importa l'ordine di foo e bar.

+0

Grande seguito. –