Domanda

Di recente, ho un'idea pericolosa nella mia testa dopo aver letto questo post sul blog. Questa idea può essere espressa in questo modo:

Non ho bisogno della maggior parte di ciò che offre la libreria standard C ++. Quindi, perché non implemento una versione meno generale, ma più facile da usare?

Ad esempio, l'uso dell'STL consente di eliminare risme di errori del compilatore incomprensibili e alterati. Ma non mi importa di allocatori, iteratori e simili. Quindi perché non impiegare un paio d'ore e implementare una classe di elenchi collegati facile da usare, ad esempio?

Quello che mi piacerebbe sapere dalla community di StackOverflow è questo: quali sono i pericoli, i possibili svantaggi e i possibili vantaggi del "lancio del mio" per la maggior parte delle funzionalità esistenti in C ++?

Modifica: sento che le persone mi hanno frainteso su questa idea. L'idea era di capire se potevo implementare una molto piccola serie di funzionalità STL che è notevolmente semplificata, più come un progetto per insegnarmi su strutture di dati e simili. Non propongo di reinventare l'intera ruota da zero, solo la parte di cui ho bisogno e di cui voglio conoscere. Suppongo che ciò che volevo capire è se la complessità dell'uso dell'STL giustifica la creazione di una versione più piccola e più semplice di se stessa.

Riutilizzando boost o simile.

La maggior parte di ciò che codice è per l'Università e non ci è consentito l'uso di librerie esterne. Quindi è la libreria standard C ++ o le mie classi.

Obiettività di questa domanda.

Questa domanda è non soggettiva. Né dovrebbe essere Wiki della comunità, dal momento che non è un sondaggio. Voglio argomentazioni concrete che evidenzino un vantaggio o uno svantaggio che possibilmente potrebbe verificarsi con il mio approccio. Contrariamente alla credenza popolare, questa non è un'opinione, ma basata sull'esperienza o su buoni argomenti logici.

Formato.

Pubblica solo uno svantaggio o un vantaggio per risposta. Ciò consentirà alle persone di valutare le singole idee anziché tutte le tue idee contemporaneamente.

E per favore ...

Nessuna guerra religiosa. Non sono un fan boy di nessuna lingua. Uso qualunque cosa sia applicabile. Per la compressione di grafica e dati (ciò su cui sto lavorando al momento) sembra C ++. Limita le tue risposte alla domanda o verranno sottoposte a downgrade.

È stato utile?

Soluzione

  

Quindi, perché non lo implemento di meno   versione generale, ma più facile da usare?

Perché non puoi. Perché qualsiasi altra cosa tu possa dire su C ++, non è un linguaggio semplice e se non sei già molto bravo in esso, l'implementazione dell'elenco collegato sarà errata.

Onestamente, la tua scelta è semplice:

Impara il C ++ o non usarlo. Sì, C ++ è comunemente usato per la grafica, ma Java ha anche librerie OpenGL. Così fa C #, Python e praticamente ogni altra lingua. Oppure C. Non è necessario utilizzare C ++.

Ma se lo usi, impara e usalo correttamente.

Se vuoi stringhe immutabili, crea la stringa come const.

E indipendentemente dalla sua implementazione sottostante, l'STL è straordinariamente semplice da usare.

Errori del compilatore C ++ possono essere letti, ma ci vuole un po 'di pratica. Ma soprattutto, non sono esclusivi del codice STL. Li incontrerai qualunque cosa tu faccia e quali librerie usi. Quindi abituati a loro. E se ti stai abituando comunque, potresti anche usare STL.

A parte questo, alcuni altri svantaggi:

  • Nessun altro capirà il tuo codice. Se fai una domanda su SO riguardo a std :: vector, o iteratori bidirezionali, tutti quelli che hanno ragionevolmente familiarità con c ++ possono rispondere. Se chiedi a My :: CustomLinkedList, nessuno può aiutarti. Il che è sfortunato, perché far rotolare il tuo significa anche che ci saranno più bug di cui chiedere aiuto.
  • Stai cercando di curare il sintomo, piuttosto che la causa. Il problema è che non capisci C ++. STL è solo un sintomo di ciò. Evitare STL non magicamente farà funzionare meglio il tuo codice C ++.
  • Gli errori del compilatore. Sì, sono cattivi da leggere, ma sono lì. Nella STL è stato lavorato molto per garantire che un uso errato causi errori del compilatore nella maggior parte dei casi. In C ++ è molto semplice creare codice che si compila, ma non funziona. O sembra funzionare. O funziona sul mio computer, ma fallisce misteriosamente altrove. Il tuo elenco collegato quasi sicuramente sposterebbe più errori nel runtime, dove rimarrebbero inosservati per un po ', e sarebbe molto più difficile da rintracciare.
  • E ancora una volta, sarà buggy. Fidati di me. Ho visto dannatamente bravi programmatori C ++ scrivere un elenco collegato in C ++ solo per scoprire bug dopo bug, in casi di bordo oscuri. E C ++ è tutti i casi limite. L'elenco collegato gestirà correttamente la sicurezza delle eccezioni? Garantirà che tutto sia in uno stato coerente se la creazione di un nuovo nodo (e quindi la chiamata al costruttore del tipo di oggetto) genera un'eccezione? Che non perderà memoria, che verranno chiamati tutti i distruttori appropriati? Sarà il tipo sicuro? Sarà come performer? Ci sono molti mal di testa da affrontare quando si scrivono classi container in C ++.
  • Ti stai perdendo una delle librerie più potenti e flessibili esistenti, in qualsiasi lingua. L'STL può fare molto che sarebbe un problema anche con la gigantesca libreria di classi gonfia di Java. Il C ++ è già abbastanza difficile, non c'è bisogno di buttare via i pochi vantaggi che offre.
  

Non mi importa degli allocatori,   iteratori e simili

Gli allocatori possono essere tranquillamente ignorati. Praticamente non hai nemmeno bisogno di sapere che esistono. Gli iteratori sono brillanti, però, e scoprirli ti farebbe risparmiare un sacco di mal di testa. Ci sono solo tre concetti che devi capire per usare efficacemente STL:

  • Contenitori: sai già di questi. vettori, elenchi collegati, mappe, set, code e così via.
  • Iteratori: astrazioni che consentono di navigare in un contenitore (o sottoinsiemi di un contenitore, o qualsiasi altra sequenza di valore, in memoria, su disco sotto forma di flussi o calcolata al volo).
  • Algoritmi: algoritmi comuni che funzionano su qualsiasi coppia di iteratori. Hai sort, for_each, find, copy e molti altri.

Sì, l'STL

Altri suggerimenti

Svantaggio: nessuno ma lo userete.

Vantaggio: Nel processo di implementazione imparerai perché la Libreria standard è una buona cosa.

Vantaggi: mangiare il proprio cibo per cani. Ottieni esattamente quello che fai.

Svantaggi: mangiare il proprio cibo per cani. Numerose persone, più intelligenti del 99% di noi, hanno trascorso anni a creare STL.

Ti ho suggerito di capire perché:

  

l'uso dell'STL spinge fuori risme di   compilatore incomprensibile e distorto   errori

prima

Svantaggio: potresti dedicare più tempo al debug della tua biblioteca di classe che a risolvere qualsiasi compito universitario che hai di fronte.

Vantaggio: probabilmente imparerai molto!

C'è qualcosa che puoi fare sui messaggi di errore STL del compilatore criptico. STLFilt ti aiuterà a semplificarli. Dal sito web STLFilt :

  

STLFilt semplifica e / o riformatta   errore e avviso C ++ a lungo termine   messaggi, con particolare attenzione a STL   diagnostica (e per MSVC 6, completamente   elimina gli avvisi C4786 e i loro   detriti). Il risultato rende molti   anche la diagnostica più criptica   comprensibile.

Dai un'occhiata qui e, se stai usando VisualC, anche qui .

Penso che dovresti farlo.

Sono sicuro che mi farò flambay per questo, ma sai, ogni programmatore C ++ qui ha bevuto un po 'troppo coolaid STL.

L'STL è un'ottima libreria, ma so per esperienza diretta che se fai il tuo, puoi:

1) Renderlo più veloce dell'STL per i tuoi casi d'uso particolari. 2) Scriverai una libreria con solo le interfacce di cui hai bisogno. 3) Sarai in grado di estendere tutte le cose standard. (Non posso dirvi quanto ho desiderato che std :: string avesse un metodo split ()) ...

Tutti hanno ragione quando dicono che sarà un sacco di lavoro. È vero.

Ma imparerai molto. Anche se dopo averlo scritto, torni a STL e non lo usi mai più, avrai comunque imparato molto.

Svantaggio: IMHO, la ricostruzione di librerie testate e comprovate è un buco rabbioso che è quasi garantito per essere più guai di quanto valga la pena.

Un po 'della mia esperienza: non molto tempo fa ho implementato la mia classe simile al vettore perché avevo bisogno di un buon controllo su di essa.

Dato che avevo bisogno di genericità, ho creato un array basato su modelli.

Volevo anche iterare attraverso di esso non usando l'operatore [] ma incrementando un puntatore come farebbe con C, quindi non calcolo l'indirizzo di T [i] ad ogni iterazione ... Ho aggiunto due metodi uno per restituire il puntatore alla memoria allocata e un altro che restituisce un puntatore alla fine. Per scorrere una matrice di numeri interi ho dovuto scrivere qualcosa del genere:

for(int * p = array.pData(); p != array.pEnd(); ++p){
  cout<<*p<<endl; 
}

Quindi quando comincio a usare i vettori dei vettori, capisco che quando era possibile si poteva allocare un grosso blocco di memoria invece di chiamare nuovo molte volte. In questo momento aggiungo un allocatore alla classe template.

Solo allora noto che avevo scritto un clone perfettamente inutile di std :: vector < > ;.

Almeno ora so perché uso STL ...

Un altro svantaggio :

Se vuoi ottenere un lavoro in C ++ quando hai finito con l'Università, la maggior parte delle persone che vorrebbero reclutare ti aspetteranno di avere familiarità con la libreria C ++ standard. Non necessariamente intimamente familiare al livello di implementazione, ma sicuramente familiare con il suo utilizzo e modi di dire. Se reimplementi la ruota nella forma della tua libreria, perderai l'occasione. Ciò nonostante, si spera che imparerai molto sul design delle biblioteche se ottieni il tuo, il che potrebbe farti guadagnare un paio di punti extra brownie a seconda di dove intervisti.

Svantaggi:

Stai introducendo una dipendenza dalla tua nuova libreria. Anche se è sufficiente e l'implementazione funziona bene, hai ancora una dipendenza. E questo può darti fastidio con la manutenzione del codice. Tutti gli altri (incluso te stesso, tra un anno o anche un mese) non avranno familiarità con il tuo comportamento unico di stringa, iteratori speciali e così via. Ci vorrà molto sforzo per adattarsi al nuovo ambiente prima che tu possa iniziare a refactoring / estensione di qualcosa. Se usi qualcosa come STL, lo sapranno già tutti, è ben compreso e documentato e nessuno dovrà riapprendere il tuo ambiente usa e getta personalizzato.

Potresti essere interessato a EASTL , una riscrittura della STL Electronic Arts documentata qualche tempo fa. Le loro decisioni di progettazione sono state principalmente guidate dai desideri / bisogni specifici nella programmazione multipiattaforma di videogiochi. L'abstract nell'articolo collegato lo riassume bene.

Svantaggio: il tuo corso universitario è probabilmente strutturato in questo modo per un motivo. Il fatto che tu ne sia abbastanza irritato (il sarcasmo non è inteso), può indicare che non stai ottenendo il paridigma e ne trarrà molto beneficio quando avrai un cambio di paradigma.

Advantage

Se guardi in MFC, scoprirai che il tuo suggerimento è già utilizzato nel codice produttivo - ed è stato così per molto tempo. Nessuna delle classi di raccolta di MFC utilizza STL.

Perché non dai un'occhiata alle librerie C ++ esistenti. Ai tempi in cui il C ++ non era così maturo, le persone spesso scrivevano le proprie librerie. Dai un'occhiata a Symbian (piuttosto orribile), Qt e WxWidgets (se la memoria mi serve) hanno raccolte e cose di base, e probabilmente ce ne sono molte altre.

La mia opinione è che la complessità di STL derivi dalla complessità del linguaggio C ++, e c'è poco che puoi fare per migliorare su STL (oltre a usare una convenzione di denominazione più sensata). Ti consiglio semplicemente di passare ad un'altra lingua, se puoi, o semplicemente affrontarla.

  

Ad esempio, l'utilizzo dell'STL sputa fuori   risme incomprensibili e mutilate   errori del compilatore

La ragione di ciò sono essenzialmente i modelli C ++. Se usi i template (come fa STL) otterrai r messaggi di errore incomprensibili . Pertanto, se implementi le tue classi di raccolta basate su modelli, non ti troverai in un posto migliore.

È possibile creare contenitori non basati su modelli e archiviare tutto come puntatori vuoti o una classe di base, ad es. Ma perdi i controlli del tipo di tempo di compilazione e C ++ fa schifo come linguaggio dinamico. Non è così sicuro farlo come sarebbe ad es. Objective-C, Python o Java. Uno dei motivi è che C ++ non ha una classe radice per tutte le classi a tutte le introspezioni su tutti gli oggetti e una gestione degli errori di base in fase di esecuzione. Invece la tua app potrebbe andare in crash e bruciare se ti sbagli sul tipo e non ti verrebbero forniti indizi su cosa sia andato storto.

Svantaggio : la reimplementazione di tutto di quel pozzo (ovvero di un alto livello di qualità) richiederà sicuramente numerosi grandi sviluppatori alcuni anni.

  

quali sono i pericoli, i possibili svantaggi e i possibili vantaggi di "far valere il mio" per la maggior parte delle funzionalità esistenti in C ++?

Potete permettervi e possibilmente giustificare la quantità di sforzo / tempo / denaro speso per reinventare la ruota?

  

Riutilizzo di boost o simile.

Piuttosto strano che non puoi usare Boost. IIRC, pezzi di contributo provengono da persone legate / che lavorano nelle università (pensa Jakko Jarvi). I lati positivi dell'utilizzo di Boost sono troppi per essere elencati qui.

  

Non "reinventare la ruota"

Svantaggio: mentre impari molto, ti arresti anche quando pensi a quali sono i tuoi veri obiettivi di progetto.

Vantaggio: la manutenzione è più semplice per le persone che erediteranno questo.

STL è molto complesso perché deve essere per una libreria per scopi generici.

Ragioni per cui STL è così:

  • Basato su interatori, quindi gli algoritmi standard richiedono un'unica implementazione per diversi tipi di contenitori.
  • Progettato per comportarsi correttamente di fronte alle eccezioni.
  • Progettato per essere 'thread' sicuro in applicazioni multi-thread.

In molte applicazioni, tuttavia, ne hai davvero abbastanza con quanto segue:

  • classe di stringa
  • tabella hash per ricerche O (1)
  • vettore / array con ordinamento / e ricerca binaria per raccolte ordinate

Se lo sai:

  • Le tue lezioni non generano eccezioni per la costruzione o l'assegnazione.
  • Il tuo codice è a thread singolo.
  • Non userete gli algoritmi STL più complessi.

Quindi probabilmente puoi scrivere il tuo codice più veloce che utilizza meno memoria e produce errori di compilazione / runtime più semplici.

Alcuni esempi per velocizzare / semplificare senza STL:

  • Stringa copia su scrittura con buffer di stringa contato di riferimento. (Non farlo in un ambiente multi-thread poiché è necessario bloccare l'accesso al conteggio dei riferimenti.)
  • Usa una buona tabella hash invece di std :: set e std :: map.
  • iteratori in stile "Java" che possono essere passati come un singolo oggetto
  • Tipo di iteratore che non ha bisogno di conoscere il tipo di contenitore (per un migliore disaccoppiamento del codice durante la compilazione)
  • Una classe di stringhe con più funzioni di utilità
  • Controllo dei limiti configurabili nei contenitori vettoriali. (Quindi non [] o .at ma lo stesso metodo con un flag di compilazione o runtime per passare dalla modalità "sicura" a "veloce")
  • Contenitori progettati per funzionare con puntatori a oggetti che elimineranno il loro contenuto.

Sembra che tu abbia aggiornato la domanda, quindi ora ci sono davvero due domande:

  1. Cosa devo fare se penso che la libreria std :: sia troppo complessa per le mie esigenze?

Progetta le tue classi che utilizzano internamente le funzionalità std :: library pertinenti per eseguire il "sollevamento pesante" per te. In questo modo hai meno da sbagliare e puoi ancora inventare la tua interfaccia di codifica.

  1. Cosa devo fare se voglio imparare come funzionano le strutture dati?

Progetta da zero il tuo set di classi di strutture dati. Quindi prova a capire perché quelli standard sono migliori.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top