La regola del 5 è un'estensione valida della regola di 3, o implica l'ottimizzazione prematura?

5

Ho familiarità con la nozione in c ++ della regola del 3 , tuttavia dal rilascio di C ++ 11 ho visto alcune fonti suggerire che dovrebbe essere esteso a una "regola di 5", Ie il costruttore di movimento e l'operatore di assegnazione del movimento dovrebbero essere implementati ogni volta che lo sono gli altri. Qual è la logica alla base di tale regola? La mia comprensione è che nella maggior parte dei casi l'implementazione della semantica del movimento è necessaria solo come ottimizzazione - mi sbaglio, o è la cosiddetta regola dei cinque sull'ottimizzazione del mio codice (e, quindi, sostanzialmente meno importante della regola del 3 , che significa evitare le insidie che possono portare a comportamenti imprevisti)?

    
posta Jules 25.12.2014 - 22:03
fonte

2 risposte

5

La semantica di Move è stata aggiunta a C ++ 11 in modo tale che la "regola di 3" sia ancora valida e sufficiente per evitare le insidie che si intende evitare (anche se ci sono modi migliori nella maggior parte delle situazioni applicando il "regola di 0" ).
Inoltre, non sono state aggiunte ulteriori insidie nella lingua che la "regola del 5" potrebbe aiutarti a evitare. In questo senso, la regola del 5 riguarda più l'ottimizzazione piuttosto che evitare le insidie.

D'altra parte, considerare la "regola di 5" come un'estensione della "regola di 3" ti aiuta a ricordare che in C ++ 11 ci sono due funzioni aggiuntive per i membri speciali a cui devi pensare quando la tua classe fa qualcosa di speciale che ha bisogno di un distruttore o di un costruttore di copia.

E anche se spostare la semantica è un'ottimizzazione, fornire un gestore di movimento e / o un operatore di assegnazione del movimento non significa che si sta ottimizzando prematuramente , proprio come selezionare l'algoritmo giusto non è un prematuro ottimizzazione.
Aggiungendo il supporto per spostare la semantica alla classe, quando ha senso, di solito richiede poco sforzo e non toglie nulla alla leggibilità / manutenibilità del codice.

    
risposta data 26.12.2014 - 11:52
fonte
5

La Rule of Five è ex idiomatica. Era solo un idioma per un brevissimo periodo prima della Regola dello Zero.

Il principio della Regola di 3 è diventato obsoleto quando la scrittura delle proprie classi di gestione delle risorse è diventata obsoleta, ovvero quando il compilatore supporta i riferimenti rvalue. Se implementi in termini di unique_ptr, che puoi virtualmente per ogni risorsa perché il deleter è così personalizzabile, hai solo bisogno di un assegnamento di copia personalizzato e di un costruttore di copia, quindi due. Se è necessario supportare la copia. Non c'è motivo di implementare il proprio distruttore, spostare l'operatore di assegnazione o spostare il costruttore nella stragrande maggioranza dei casi.

Il codice della regola dei tre non è rotto ma è molto più difficile da mantenere rispetto al codice della regola zero e non altrettanto efficiente. Le operazioni di spostamento offrono la correttezza in molti casi come unique_ptr , quindi dovresti sforzarti di supportarle ovunque sia possibile.

Sono le operazioni di copia che ora sono ampiamente ridondanti di fronte alle mosse, non il contrario.

In altre parole, unique_ptr è così flessibile e le operazioni predefinite sono così utili che non c'è quasi mai alcun motivo per implementare i propri membri speciali. In effetti, non c'è praticamente alcun motivo per implementare le tue classi di gestione delle risorse. E dal momento che queste classi praticamente non esistono mai, non c'è motivo di avere un idioma per costruirle.

    
risposta data 26.12.2014 - 13:40
fonte

Leggi altre domande sui tag