Le regole per la generazione automatica di funzioni speciali di spostamento (operatore costruttore e assegnazione) in C++ 11 specificano che nessun distruttore può essere dichiarato. La logica è presumibilmente che, se devi fare qualcosa di speciale nella distruzione, che una mossa potrebbe non essere sicura.C++ 11 distruttori virtuali e generazione automatica di funzioni speciali di spostamento
Tuttavia, per le chiamate di distruttore corrette nel polimorfismo, è necessario dichiarare un distruttore di classi di base come virtuale (altrimenti l'eliminazione di un'istanza di una sottoclasse attraverso un puntatore della sua classe base non concatena correttamente il distruttore).
Suppongo, quindi, che anche un distruttore vuoto impedisca al compilatore di generare automaticamente funzioni di spostamento speciali. Come in:
class Base {
virtual ~Base() { }
};
È possibile, tuttavia, di default il distruttore, come in:
class Base {
virtual ~Base() = default;
}
Così Domanda 1: Sarà questo permettere al compilatore di generare automaticamente le funzioni speciali mossa?
C'è un problema con il distruttore di default esplicito, tuttavia. Almeno nel caso di GCC 4.8.2, la firma è implicitamente cambiata in non eccezionale. Come in:
class Base {
virtual ~Base() = default; // compiler changes to:
// virtual ~Base() noexcept;
}
Mentre non ho alcun problema con noexcept in un distruttore, questo avrebbe rotto il seguente codice "client":
class Sub : public Base {
virtual ~Sub(); // this declaration is now "looser" because of no noexcept
}
domanda SO 2 è più al punto: esiste un modo per consentire la generazione automatica di funzioni speciali di spostamento in C++ 11 e consentire il corretto concatenamento del distruttore alle sottoclassi (come descritto sopra), tutto senza interrompere la sottoclasse (codice "client")?
Perché '~ Sub' è più lento? I distruttori senza specifiche di eccezione sono impostati su "noexcept". – Pradhan
La domanda sembra ben definita, ma per interesse, hai un esempio del perché questo potrebbe essere necessario? Questo sembra uno strano miscuglio di valori e semantica di riferimento. Mi sembra che nei casi in cui si voglia utilizzare il movimento (o anche la copia) non si voglia un comportamento polimorfico. E più al punto che la copia o lo spostamento predefinito sicuramente non avrà alcun comportamento polimorfico. – tahsmith
@tahsmith l'obiettivo è di rielaborare le classi base in modo tale che esse e le loro sottoclassi possano trarre vantaggio dalla semantica del movimento senza infrangere le sottoclassi. – notlesh