L'STL è implementato con OO?

8

Esistono diversi modelli di progettazione come Adattatore, Iterator implementato in STL.

Significa che STL è implementato con concetti OO?
Qual è la relazione tra OO e le parti del modello di C ++?

Ho appreso che la funzione membro virtuale che giustifica l'OO è contraddittoria con template, è corretto?

    
posta upton 07.08.2012 - 09:24
fonte

8 risposte

11

Innanzitutto, "STL" non è un termine ufficiale, è il nome della libreria proposto per includere la libreria standard C ++ quando non c'erano contenitori. Fornisce essenzialmente modelli di container e algoritmi.

Ora, questi modelli di contenitori e algoritmi sono ... modelli in modo da produrre tipi secondo necessità. Non si basano sull'eredità dal punto di vista dell'utente.

Tuttavia, la libreria standard specifica essenzialmente l'interfaccia della libreria, non l'implementazione. Molte implementazioni STL useranno un po 'di orientamento agli oggetti nella loro implementazione ma come utente non lo vedrete se non vi immergete nel codice sorgente delle implementazioni (che devono essere esposte in quanto è essenzialmente un codice template).

I learned that virtual member function which justifys the OO is contradict with template, is this correct?

No, sono concetti ortogonali che forniscono serie di vantaggi e svantaggi molto diversi. Infatti, in C ++, uno dei vantaggi chiave per l'utilizzo di tale linguaggio è che entrambi sono disponibili e l'utilizzo di uno non annulla l'utilizzo dell'altro. È persino un grande vantaggio. Ad esempio, uno degli idiomi più interessanti in C ++ è CRTP che utilizza sia i modelli che l'ereditarietà. L'idea è che la parte ereditari ti consente di estendere diversi tipi con un comportamento e dati comuni, come una classe base; mentre la parte template si assicura di generare classi base specifiche per ogni bambino, rendendo impossibile avere un puntatore a tutte le classi usando la classe CRTP come base. Ciò è estremamente utile e non consente di creare confusione con l'ereditarietà laddove non dovrebbe esserci.

Ho anche implementato sistemi di dispacciamento di eventi molto generici che non conoscevano né tipi di eventi o tipi di listener, ma codici combinati interni dinamici e statici che insieme consentivano di generare i giusti tipi interni corrispondenti ai giusti tipi di runtime.

E questo è il punto: non è sempre necessario "l'orientamento all'oggetto". In effetti, il più delle volte non ne hai affatto bisogno, devi definire alcuni tipi e usarli direttamente come parte diversa di un qualche tipo di motore astratto (composizione). Non è sempre necessario il codice generico, ovvero i modelli. A volte è necessario generalizzare una funzione da applicare a diversi tipi non correlati. Quando sono correlati puoi usare la loro classe base e non avere bisogno di modelli.

Hanno diversi vantaggi e costi completamente diversi, quindi sono buoni da combinare per risolvere problemi complessi.

STL è un buon esempio di un problema in cui la maggior parte riguarda i tipi di provvedere (contenitori) e le funzioni (algoritmi) correlati a un determinato tipo anziché una gerarchia di oggetti runtime. Nella libreria standard, gli stream sono realizzati in un modo che è tipico dell'orientamento agli oggetti: è una gerarchia di classi di stream che fa cose diverse in un modo che consente di definire una classe di sub-stream che combina diversi comportamenti / capacità. Lì, l'orientamento all'oggetto è utile, anche se alcune persone preferirebbero che fosse più simile al STL (non sono uno specialista in materia).

Quindi, considerali come strumenti molto diversi, come un cacciavite e un martello. C ++ non ti lascia pensare con un solo strumento in mente.

    
risposta data 07.08.2012 - 10:26
fonte
8

In realtà, la STL ha introdotto il paradigma Programmazione generica al mainstream.

Quando mi è stato insegnato il paradigma Programmazione orientata agli oggetti (di qualche professore) 15 anni fa, mi è stato insegnato che i tre pilastri fondamentali sono l'incapsulamento, l'ereditarietà e il polimorfismo (oggi quest'ultimo dovrebbe probabilmente essere qualificato come polimorfismo runtime ), mentre Wikipedia attualmente elenca astrazione dati, incapsulamento, messaggistica, modularità, polimorfismo ed ereditarietà come definizione delle caratteristiche OOP. Naturalmente, l'STL usa alcuni di essi, come l'incapsulamento, ma poi usa anche funzioni, che sono una caratteristica del paradigma Programmazione strutturata . Eppure nessuno potrebbe obiettare che l'STL è Programmazione strutturata .

Si noti che una delle caratteristiche più forti di C ++ è il fatto che supporta molti paradigmi di programmazione (strutturata, orientata agli oggetti, generica, programmazione funzionale e altro) e che brilla di più brillante dove si mescolano e si mescolano.

    
risposta data 07.08.2012 - 14:12
fonte
6

Per citare Alexander Stepanov dalla sua intervista STLPort :

STL is not object oriented. I think that object orientedness is almost as much of a hoax as Artificial Intelligence. I have yet to see an interesting piece of code that comes from these OO people. [...] I find OOP philosophically unsound. It claims that everything is an object. Even if it is true it is not very interesting - saying that everything is an object is saying nothing at all. I find OOP methodologically wrong.

Detto questo, un'implementazione individuale potrebbe essere eseguita usando l'ereditarietà e il polimorfismo in alcuni punti. Ad esempio, ho visto un'implementazione in cui iterator è stata ricavata da const_iterator per supportare la conversione implicita da iterator a const_iterator . La derivazione è non tuttavia, caratteristica o richiesta dal design.

In conclusione: mentre si può / potrebbe usare il codice orientato agli oggetti per implementare alcune parti dell'STL, il progetto dello STL stesso è (enfaticamente) non orientato agli oggetti.

    
risposta data 18.08.2012 - 06:21
fonte
3

No, direi che l'STL non è particolarmente OO, semmai si adatta più a uno stile di programmazione funzionale. In particolare:

  • std :: gli algoritmi sono funzioni libere non metodi
  • spesso prendono oggetti funzione così:. sono funzioni di ordine superiore
  • operano su qualsiasi contenitore
  • std :: transform è una mappa, le funzioni X_if sono filtri, std::accumulare è piegare / ridurre

allo stesso modo si può obiettare che i contenitori stessi sono monadi

  • l'istanziazione del modello è una costruzione di tipo
  • le sequenze hanno almeno costruttori di unità, ad es. %codice%
  • fmap è std :: transform
  • bind e / o join sono implementabili (anche se non forniti fuori dalla scatola)
  • qualsiasi ragionevole implementazione di binding / join soddisferà le leggi monad

Per le altre domande, le parti OO e le parti del modello di C ++ sono separate e le funzioni virtuali non escludono la presenza di modelli. Nel caso dell'STL, il design non sceglie di utilizzare le funzioni virtuali.

    
risposta data 07.08.2012 - 10:08
fonte
3

Dipende da chi chiedi una definizione di OOP, perché OOP è un termine notoriamente mal definito e non esiste un buon consenso su ciò che costituisce OOP e cosa no.

Dal punto di vista di una persona Java, la risposta è probabilmente "no" poiché la libreria di algoritmi di C ++ non si occupa del polimorfismo di run-time, non usa l'ereditarietà della classe e perché la sintassi non sembra OOP- y.

D'altra parte, chiedi a un programmatore funzionale e la risposta potrebbe essere "sì" .

Ecco come Wikipedia definisce OOP:

Object-oriented programming (OOP) is a programming paradigm using "objects" – data structures consisting of data fields and methods together with their interactions – to design applications and computer programs. Programming techniques may include features such as data abstraction, encapsulation, messaging, modularity, polymorphism, and inheritance. Many modern programming languages now support OOP, at least as an option.

Tutti questi sono realizzati, o aiutati, nella libreria standard del C ++, e in particolare nella parte che tratta di contenitori e algoritmi. In particolare, gli algoritmi rafforzano l'incapsulamento e l'astrazione (e quindi la modularità) e sono polimorfi attraverso l'uso di modelli.

    
risposta data 07.08.2012 - 13:54
fonte
1

A mio parere, STL si occupa più di algoritmi su contenitori iterabili rispetto a OO.

Definisce un'interfaccia comune (l'iteratore) da implementare per utilizzare gli algoritmi.

Gli iteratori C / C ++ sono chiamati enumeratori / enumerabili in Java e C #

Forse STL è più orientato all'aspetto di OO.

    
risposta data 07.08.2012 - 09:38
fonte
1

I learned that virtual member function which justifys the OO

Dove diavolo hai sentito?

I principi fondamentali dell'orientamento agli oggetti sono l'incapsulamento e l'astrazione. Le funzioni virtual sono solo uno dei mezzi con cui viene raggiunto. Non sono assolutamente necessari per l'effettivo orientamento dell'oggetto. In effetti, un modello è un mezzo perfettamente adatto. Potrebbe non essere un'eredità, ma è ancora una sorta di polimorfismo. E alcune classi non richiedono né.

I contenitori della libreria Standard sono assolutamente orientati agli oggetti. Incapsulano tutti i dettagli non necessari dall'interfaccia e riassumono l'implementazione al massimo ragionevolmente possibile.

    
risposta data 07.08.2012 - 14:01
fonte
-1

L'implementazione OOP, da sola, non significa nulla finché non definisci cosa intendi per "oggetto". Se gli oggetti sono valori (non entità, come la maggior parte dei cosiddetti linguaggi OOP ma C ++ assume), quindi STL è OOP altrimenti no.

Assumi questo frammento di codice:

Person a("joe");
Person b = a;

Sono a e b due rappresentazioni di una stessa persona vivente o solo due esseri viventi con lo stesso nome?

Qual è l'oggetto? a , b o la persona vivente che rappresentano?

Inoltre, l'ereditarietà C ++ è un meccanismo di aggregazione tecnica diverso dall'ereditarietà dell'oggetto (ovvero un'astrazione). I due possono coincidere se imponiamo una certa disciplina (come gli oggetti sono tutti accessibili tramite indiretta e sono tutti sostituibili - questo significa che tutti i metodi rilevanti sono virtuali) altrimenti possono bersagliare obiettivi diversi (l'ereditarietà del C ++ non è altro che una "composizione implicita" )

I modelli possono anche (tramite specializzazione) offrire meccanismi di "sostituzione", basati su tipi statici piuttosto che su tipi dinamici (basati su funzioni virtuali) e in questo senso - se una stessa disciplina viene utilizzata in fase di compilazione - fornire una compilazione tempo OOP.

In sostanza, non gli schemi di aggregazione e dispacciamento di C ++ sono di per sé OOP o giustificano OOP. Possono fare anche altre cose. OOP è una metodologia astratta per descrivere e collegare l'oggetto insieme. Tali relazioni possono essere associate all'ereditarietà e alla distribuzione virtuale se i tipi di oggetto dipendono dall'esecuzione in fase di esecuzione o possono essere associati alla specializzazione del modello e alle conversioni implicite se i tipi di oggetto possono essere definiti durante la compilazione. L'ereditarietà può essere solo uno dei modi per fornire una conversione implicita tra riferimenti e puntatori.

    
risposta data 07.08.2012 - 10:54
fonte

Leggi altre domande sui tag