Sto cercando di imparare le migliori pratiche per la progettazione del codice e il riutilizzo in C ++, quindi sto passando attraverso i ben noti elementi GoF D esign Patterns del software orientato agli oggetti riutilizzabile.
Ho notato che quasi tutti i modelli di progettazione utilizzano oggetti allocati dinamicamente. Per evitare perdite di memoria, mi sto orientando verso l'utilizzo di shared_ptr
per tutte queste classi. Fondamentalmente, shared_ptr
di solito punta a un'interfaccia di classe astratta e questo è il modo in cui gli oggetti interagiscono tra loro.
Quando cerco la discussione su shared_ptrs per C ++, la gente dice che se tu usi shared_ptrs ovunque nel tuo codice C ++, probabilmente stai facendo cose sbagliate . Queste persone sanno di cosa stanno parlando o dovrei fermamente mantenere l'allocazione dinamica dell'heap per tutti i miei oggetti?
Ecco un esempio che ho trovato dei commentatori che dicono di evitare questa pratica di progettazione: link
Esempio di interfaccia comune
std::shared_ptr<Inferface> item1(new ConcreteClassA());
std::shared_ptr<Inferface> item2(new ConcreteClassB());
item1->Action();
item2->Action();
Esempio di evitare interfacce comuni e allocazione heap
void Action(ConcreteClassA item){
item.Action();
}
void Action(ConcreteClassB item){
item.Action();
}
ConcreteClassA item1;
ConcreteClassB item2;
Action(item1);
Action(item2);
Il primo esempio è chiaramente superiore per il riutilizzo del codice poiché non devo scrivere nuove funzioni per ogni nuova classe, ma ciò implica shared_ptrs e allocazione dell'heap. Questo è un esempio molto semplice del perché i pattern di progettazione sono utili e ovviamente è molto più complicato di così.
Sono in un punto di confusione su quale approccio è considerato una pratica comune per la progettazione di software con C ++. Diciamo che sto facendo software applicativo che avrò bisogno di mantenere in più anni, come un esempio di editor di testo WYSIWYG dal libro GoF. Quando la gente dice che non si dovrebbe usare ampiamente shared_ptr per gestire gli oggetti vuol dire che dovrei usare altri puntatori intelligenti / puntatori grezzi o è la pratica comune del C ++ per evitare del tutto l'allocazione dinamica dell'heap?
Per me, OOP ha più senso per un linguaggio come Java, dove la garbage collection è automatica e le interfacce fanno parte del linguaggio.
La pratica del settore è di seguire schemi di progettazione che utilizzano l'allocazione diana durante lo sviluppo di applicazioni in C ++? Se è così, i puntatori intelligenti sono la giusta strada da percorrere?