Newsgroup: it.comp.lang.c++
Titolo: impedire copie e assegnazioni di un oggetto

Vorrei che non fosse possibile chiamare il costruttore di copia o
l'operatore di assegnazione su oggetti di una certa classe creata da
me. Come devo fare?
Ho pensato di metterli nella parte privata della classe ma non mi
sembra un modo molto elegante
Ancora: come devo fare per impedire che ci siano in uno stesso
programma più oggetti della stessa classe?
grazie e buon millennio a tutti! 

 wrote in message 386ba539...@news.mclink.it...


 programma più oggetti della stessa classe?
A questo problema, detto della "singleton pattern", esistono
varie soluzioni canoniche.  La piu` semplice e` di definire
privati tutti i costruttori della classe, delegandone l'accesso
a uno schema di fabbrica; naturalmente, dovrai decidere
cosa fare se vengono richiesti molteplici "copie" mentre tu
vuoi fornirne una sola (classicamente, si fornisce l'accesso
sempre alla stessa copia, ma potresti anche considerarlo un
errore e dare un'exception).
Personalmente, apprezzo di piu` la pattern alternativa
"stateless proxy": la classe concreta e` implementata "in
segreto" (definita solo in un .cpp), le sue funzionalita` si
accedono tramite un'interfaccia astratta, il codice-cliente
usa sempre una classe leggerissima detta "stateless
proxy" (di cui puo` farsi tutte le copie che vuole, tanto...)
che delega tutto alla classe vera.  Per esempio, usando
solo implicitamente il concetto di interfaccia astratta,
potremmo avere:
-- nel file di header errorlog.hpp:
    class errorlog {    // stateless-proxy al log degli errori
    public:
        errorlog();
        void append_error(const char* message);
        // ecc
    };
Il codice-cliente include questo, ne istanzia quante copie
ne vuole, eccetera.  Nota che la classe e` totalmente
priva di stato (costo intrinseco di una istanza, 0 byte,
anche se probabilmente il tuo compilatore te ne fara`
pagare 4).
-- nel file di implementazione errorlog.cpp:
    #include "errorlog.hpp"
    class errorlog_singleton {    // il vero log degli errori
    private:    // tutto privato...
        friend class errorlog;       // la parte che esponiamo
        void append_error(const char* message) {
            // la vera implementazione di append_error
        }
        // ecc
    };
    static errorlog_singleton the_log;
    void errorlog::append_error(const char* message) {
        the_log.append_error(message);
    }
    // ecc
E` un tipico caso di un singolo componente (lo "error log")
diviso fra due classi, la "class errorlog" che ha il ruolo di
essere esposta al codice cliente, e la "class errorlog_singleton"
che ha invece il ruolo di fare il lavoro.  L'uso di "friend",
d'altra parte, e` tipico appunto di questi casi (un solo
componente, ma diviso in due classi distinte fra loro per
una qualche specifica ragione).
Il problema dell'inizializzazione e della terminazione del
singleton si puo` qui affrontare in vari modi.  Un reference
count basato sul numero di stateless proxy esistenti, a
volte, puo` offrire l'approccio piu` adeguato, ad esempio.
Alex

 volte, puo` offrire l'approccio piu` adeguato, ad esempio.
Non sarebbe possibile inizializzare the_log indipendentemente da quante
volte è istanziata error_log evitando l'uso di reference-count?
EMG

     }
Effettivamente il risultato appare piu' usabile di un Singleton,
soprattutto se deve essere incrementato con meccanismi tipo reference
count e simili; dal punto di vista della sua implementazione pero' trovo
un po' noioso dover scrivere tutte i metodi di ridirezione. Mi
piacerebbe anche riuscire a templatizzarlo, ma di primo acchito non vedo
la soluzione. Idealmente mi piacerebbe avere una classe astratta che
definisce l'interfaccia, una classe concreta che la implementa ed un
meccanismo generico che collega le due; l'impossibilita' di definire un
proxy implicito (almeno senza ridefinire * o &, cosa che introdurrebbe
altri problemi) mi pare un problema insormontabile.
Ciao,
Nicola

 volte è istanziata error_log evitando l'uso di reference-count?
Possibilissimo, ma non e` detto che sia ottimale.  Supponi ad
esempio che the_log, sinche` e` attiva, debba tenere bloccate
un tot di risorse; in questo caso, siamo motivati a inizializzarla
il piu` tardi possibile, e liberarla non appena possiible -- questo
e` permesso dall'approccio a reference-count, cui accennavo.
In generale, l'inizializzazione e la terminazione di oggetti con
lifetime static possono dare problemi, e questo puo` dare una
altra motivazione alla gestione esplicita di startup/shutdown.
Se non si applicano queste considerazioni, cioe` se in un dato
caso _non c'e` proprio_ un "problema di inizializzazione e di
terminazione", allora non e` il caso di "affrontarlo":-).
Alex

 altri problemi) mi pare un problema insormontabile.
C++ e Java purtroppo mancano di meccanismi di "delegazione
generica" paragonabili a quelli offerti da __getattr__ ecc di Python
(o dai meccanismi di "meta-classe" di altri ambienti).
Il meccanismo "eredita` di implementazione" offre una singola
possibilita` di delegazione, purtroppo molto rigida e limitata; e`
un prezzo molto alto da pagare per il solo scopo di evitare di
scrivere codice boilerplate, e non risolve tutti i problemi.
Se si e` sufficientemente allergici al boilerplate da essere pronti
a pagare i prezzi necessari, si parte con una serie di macro:
    METHOD0(return_type, method_name)
    METHOD1(return_type, method_name, arg1_type, arg1_name)
(ecc ecc)
e se ne scrivono le varie implementazioni, che permettono di
scrivere poi "una volta sola" qualcosa del tipo:
    CLASS_DECL(BaseName)
        METHOD0(void, aMethod)
        METHOD1(int, anotherMethod, int, x)
    CLASS_END()
che a seconda delle diverse implementazioni delle macro si
espandono a:
    class IBaseName {
    public:
        virtual void aMethod() = 0;
        virtual int anotherMethod(int x) = 0;
    };
oppure:
    class BaseName_impl: public IBaseName {
    public:
        virtual void aMethod();
        virtual int anotherMethod(int x);
    };
oppure:
    class BaseName: public IBaseName {
        friend class BaseName_factory;
        IBaseName* pDelegatee;
        BaseName(IBaseName* pD): pDelegatee(pD) {}
    public:
        void aMethod() { pDelegatee->aMethod(); }
        int anotherMethod(int x) { return pDelegatee->anotherMethod(x); }
    };
e cosi` via (o vari schemi analoghi, naturalmente).
Non e` affatto una soluzione entusiasmante...!
Alex

 e` controproducente.
Non sempre. Lo scopo di uno header file (piu' esattamente di un .h e di
un .cpp) puo' essere quello di SEPARARE e non solo quello di
CONDIVIDERE. Probabilmente non mi sono spiegato bene: ritengo che possa
essere vantaggioso separare wrapper e proxy, sia come interfaccia che
come implementazione, ad esempio per permettere di trasferire il proxy
in una libreria dinamica.
[...]
Per il resto concordo con te che le opzioni per limitare la stesura
manuale del codice relativo a questo idioma non sono soddisfacenti.
Tanto vale scrivere a mano...
Ciao,
Nicola

 in una libreria dinamica.
Il proxy, nella pattern "stateless proxy", e` una classe virtualmente
priva di peso: pochissimo codice, niente dati, nessuno 'spessore' di
concetto.  Il suo strettissimo accoppiamento con il 'singleton' per cui
fa da rivestimento permette tutto questo; il 'singleton' stesso puo`
avere metodi solo inline (anche se grossi, visto che comunque se ne
ha una sola incarnazione!).  Non vi e` nessun livello di indirettezza;
le prestazioni sono dunque ottimali.  Quali vantaggi si potrebbero mai
avere a "separare" le implementazioni delle due classi proxy e
'singleton', che sono parti strettamente integrate ed accoppiate
dello stesso componente?
Puo` darsi che tu abbia in mente altre pattern similari, come
'flyweight', 'proxy' (senza aggettivi), eccetera.  Ma se stiamo
parlando di 'stateless proxy', come da subject di questo thread,
continuo a pensare che dividere l'implementazione in due file,
da mantenersi per sempre congiunti, abbia 0 (leggasi, zero)
vantaggi, a fronte di costi comunque >0 (benche` non enormi);
il rapporto costi/benefici tende dunque all'infinito, quindi...:-)
Alex

 un tot di risorse;
Giusto! Non ci avevo riflettuto abbastanza.
EMG

 in una libreria dinamica.
A me sembra che anche in questo caso la separazione serva alla
condivisione. Infatti lo scopo di una libreria dinamica qual'è se non
quello di condividere?
EMG

 EMG
Ad esempio, posto che lavoriamo ad uno stesso progetto, separare quello
che faccio io da quello che fai tu, per poter aggiornare le due parti
presso gli utenti separatamente.
Ciao,
Nicola

Nicola Musatti <Nicola....@ObjectWay.it> wrote in message
3870E385...@ObjectWay.it...

...il che sarebbe decisamente un disastro fra uno stateless proxy e
il singleton che esso ricopre, visto l'assoluto accoppiamento fra di
essi, naturalmente.
Questo, mi pare, sottolinea ulteriormente quanto _assolutamente_
inappropriata sia la tua _assoluta_ preferenza per porre sempre
le dichiarazioni in un file di header, senza tenere in nessun conto
le effettive condizioni di una particolare design pattern.
Alex

 presso gli utenti separatamente.
Mi sfugge qualcosa: come fai ad aggiornare, presso il cliente,
separatamente due parti di una stessa applicazione? Dovrebbero essere
due eseguibili diversi. Ma in questo caso che senso ha parlare di header
e moduli separati? Forse che uno lavora sull'header e l'altro sul
modulo?
EMG

 wrote in message news:3870FF87...@flashnet.it...

In termini generali (ma non coperti dallo standard C++, quindi forse
OT in questo gruppo!) una applicazione puo` (e, spesso, dovrebbe)
essere distribuita come una collezione di componenti separati (delle
DLL su Windows, delle .so su vari Unix, ecc) che, se relativamente ben
disaccoppiati, possono in effetti essere aggiornati separatamente.
Nei termini piu` generici possibili, un "componente" e` un insieme di
"deliverables" (diciamo "files" che sono "consegnabili" all'utente del
componente) che sono rilasciati e aggiornati assieme.  In pratica, il
modello degli "aggiornamenti separati" funziona cosi`-cosi`, perche`
il test d'integrazione, o system test che dir si voglia, non puo` essere
compiuto su tutte le possibili combinazioni di vari rilasci/livelli per i
vari componenti.  Vi sono nondimeno vantaggi metodologici a ragionare
e progettare in termini di componenti (o "sottosistemi" che dir si voglia)
con particolare attenzione alle dipendenze fra di essi (sia in termini
assoluti, esistenza di una certa dipendenza diretta o indiretta A->B
fra componenti, sia in termini relativi, "spessore" o "natura" della
dipendenza).  Ad esempio, la fortissima dipendenza indotta da pratiche
come la eredita` di implementazione e` fra gli argomenti che militano
contro la prassi stessa.
Il testo canonico sulla componentizzazione in C++ (standard) e` il
Lakos, "Large Scale C++ Programming".
Naturalmente, lo "stateless proxy", di cui in teoria stiamo parlando
su questo thread, e` un purissimo esempio di "singolo componente";
sarebbe ridicolo pensare di testare o aggiornare separatamente il
"singleton" e il suo "proxy privo di stato", che sono due classi che,
in modo assolutamente ovvio, costituiscono una partizione di un
SINGOLO componente.
L'incapacita` di ragionare in termini di componenti, cadendo invece
nel trabocchetto di identificare come "pseudo-componente" una
CLASSE (che componente, in generale, non e`, bensi`, spesso e
volentieri, PARTE di un componente!), e` fra i trabocchetti piu`
classici in cui puo` cadere un progettista, soprattutto quando
inizia a muovere i primi passi ad un livello di "scala" di software
cui non e` abituato (credo che ci siamo caduti un po' tutti...:-).
I paradigmi di progettazione (e implementazione) a oggetti vanno
propriamente considerati come _utili approcci_ in _direzione_
della progettazione di software ben partizionato per componenti
(cosi` come quelli del "generic programming", e altri ancora).
Oltre al testo di Lakos, consiglio il conciso e brillante "Multi
Paradigm DESIGN for C++", di Coplien, e piu` o meno tutti i
lavori pubblicati di Robert Martin (in buona parte reperibili in
rete, spesso naturalmente sotto forma di file .PDF per cui
temo che tu personalmente li troverai detestabili:-), comunque
vedi, ad esempio:
http://www.objectmentor.com/base.asp?id=42
per un buon elenco di molti degli articoli disponibili.
Alex

 temo che tu personalmente li troverai detestabili:-)
Scusa se torno sull'argomento ma secondo te un file PDF può essere letto
agevolmente senza stamparlo? Io ci ho provato una volta e mi è bastato.
Forse esistono dei lettori migliori del classico Acrobat che mi sembra
uno strumento dedicato alla stampa e non certo alla lettura in linea del
documento?
EMG

 documento?
"Classico"?  Acrobat Reader 4.05 l'ho scaricato sara` un mese al massimo,
ed era rilasciato di fresco.
Mi sembra che con questo release del Reader (Acrobat verace non lo
conosco, e` un prodotto commerciale e non economicissimo) "ce la si
cavi", dipende naturalmente anche dal documento (personalmente, le
cose tendo a stamparle, se no, leggerle in autobus [che e` dove, grazie
a circa 1 ora ogni mattina e ogni sera, mi faccio una cultura:-] diviene
scomodo...:-).
Alex

 scomodo...:-).
Sono d'accordo con te. Io, molto tempo fa, la cultura me la facevo ai
semafori (ora sono anni che ho praticamente smesso di utilizzare l'auto)
e quindi ti capisco perfettamente. :-)
EMG

 dello stesso componente?
Innanzitutto mi sono accorto di aver confuso proxy con singleton nel mio
messaggio precedente, anche se questo direi che non sposta il tuo
argomento.
Se da una parte e' vero che non ha molto senso separare gli oggetti (=
.obj) relativi a proxy e singleton, vedo comunque alcuni vantaggi nel
separare il codice:
- Ordine;
- Maggior semplicita' nell'ipotesi di sostituire lo stateless proxy con
un altro 
  meccanismo in futuro.
Ciao,
Nicola

 per un buon elenco di molti degli articoli disponibili.
Il libro di Coplien lo sto leggendo: effettivamente e' tra i pochi che
fanno davvero bene al cervello! A Robert Martin spero di arrivare prima
della pensione...
Ciao,
Nicola

 le effettive condizioni di una particolare design pattern. 
Credo di aver chiarito l'equivoco in un altro messaggio, ma continuo a
preferire la separazione tra dichiarazione e implementazione.
Ciao,
Nicola

 preferire la separazione tra dichiarazione e implementazione.
Giustissimo principio, in generale, cosi` come un martello e` un
giustissimo strumento per molti compiti.
Qui, naturalmente, stai (nel migliore dei casi) usando un martello
per rompere le noci (ce la puoi fare, ma uno schiaccianoci sarebbe
piu` appropriato), se non addirittura per infilare viti (nel qual caso
consiglierei _decisamente_ un cacciavite...:0).
Il principio giusto e`, separazione fra *interfaccia* e implementazione.
Ebbene, in certi casi le definizioni di classi (tecnicamente, non e`
di _dichiarazioni_ che stiamo parlando...) fanno parte proprio
dell'implementazione, non dell'interfaccia.  In questi casi (certo
la minoranza, ma importanti) sarebbe sbagliato separarle in
modo totalmente arbitrario dal resto dell'implementazione, solo
perche` in tanti altri casi fanno parte invece dell'interfaccia.
Alex

 della pensione...
Gli articoli di Martin disponibili all'URL che ho nominato sono gratis,
e meno avanzati/difficili secondo me della gran parte di quello che
ha da dire Coplien.
Alex

   meccanismo in futuro.
Maggiore complicazione, anzi, perche`, invece di UN file di
implementazione, dovrai coordinare tutte le modifiche fra
DUE (o piu`) file di implementazione, che hai arbitrariamente 
scelto di embricare con l'uso del preprocessore (#include)...
Ordine e manutenibilita` sono entrambi fra gli _svantaggi_
di questa strana e inappropriata scelta di usare il preprocessore
quando se ne puo` benissimo e con vantaggio fare a meno.
Alex

Salvo che il proxy e' una classe semanticamente poverissima e puo'
risiedere in un file sorgente piccolo (ovvero che costa poco
ricompilare). Il singleton invece e' verosimilmente una classe ricca e
quindi passibile di modifiche anche senza che cambi la sua interfaccia.
Potrebbe addirittura convenire scomporre la sua implementazione in piu'
file sorgenti.
La separazione tiene conto anche di queste caratteristiche, che
differenziano notevolmente due classi anche se concettualmente
strettamente legate tra loro. Tra l'altro trovo che proprio la scarsa
separazione tra proxy e singleton costituisca uno svantaggio rispetto ad
altri schemi, forse compensabile introducendo una classe base astratta
comune a proxy e singleton (ma dovrei pensarci di piu').
Ciao,
Nicola

 comune a proxy e singleton (ma dovrei pensarci di piu').
Puo` darsi che tu pensi sin troppo, senza concreta esperienza
su cui fondare la materia di questi pensieri.  Il singleton nella
pattern stateless proxy e` fatto per *non essere mai visto da
fuori* del componente stesso, quindi, _a che pro_ introdurre 
una interfaccia astratta come sua classe base?!  Il codice-cliente
non la vedra` comunque mai.
Il proxy potrebbe anche avere una classe-base astratta, nel
caso (che non ho mai visto succedere, ma non mi sembra
escludibile a priori) che esso debba interagire anche in _altre_
pattern, del tutto al di fuori di quella singleton/stateless-proxy;
questa interfaccia astratta, se del caso, il proxy dovrebbe poi
condividerla con _altre_ classi, con le quali verra` usato in
modo intercambiabile e polimorfo (questo, ricordo, e` lo scopo
unico e solo delle interfacce, o classi-base astratte che dir si
voglia: l'uso intercambiabile e polimorfico di molteplici classi
concrete in modo 'trasparente' al codice-cliente).
L'eventuale classe-base astratta del proxy stateless dunque, se
anche vi fosse, non avrebbe a che vedere con la sua partecipazione
nella pattern stessa, ma solo con quella in _altre_ pattern.
Alex

 si applicano al *componente*, NON alla *classe*.
Non correre nell'assumere livelli di esperienza o di competenza a
partire solo da quello che leggi nelle news. Penso che ciascuno si crei
con il tempo un modus operandi che raccoglie le soluzioni che gli sono
tornate utili, che in parte sono mutuati dal contatto con gli altri
(persone o letture) ed in parte derivano dall'esperienza diretta (nel
qual caso e' possibile che in parte si tratti dell'espressione di gusto
personale). C'e' sempre spazio per migliorare, ma non e' detto che cio'
che funziona per qualcun altro funzioni anche per se'.
Rispetto a quello che dici ritengo altrettanto vero che non
necessariamente "un componente == un file sorgente" (e nemmeno una
coppia .h/.cpp).
Ciao,
Nicola

 ha da dire Coplien.
Prima o poi mi scarichero' qualcosa. Per quanto riguarda Coplien trovo
"Multiparadigm..." decisamente piu' facile da leggere di "Advanced C++",
che pero' ho letto qualche anno fa.
Ciao,
Nicola

 perche` in tanti altri casi fanno parte invece dell'interfaccia.
Non so cosa dica lo standard; se non sbaglio secondo Stroustrup i due
termini sono intercambiabili nel caso del costrutto class <name> {
<members> }; perche' effettivamente e' piu' di una dichiarazione, ma non
e' esattamente una definizione.
Ciao,
Nicola

 > Gli articoli di Martin disponibili all'URL che ho nominato sono gratis,
Gli articoli di Martin sono un buon punto d'inizio per il discorso "ragionare
per componenti".
Per le anti-pattern in generale, Brown, Malveau, McCormich, Mowbray,
"AntiPatterns", John Wiley 1998.  Non mi pare che "pseudo-component"
la identifichino come tale loro, pero` (i loro nomi sono MOLTO piu`
coloriti...).
Alex

 coloriti...).
Com'e' questo libro? Io sono prevenuto in proposito a causa della
presenza di T. Mowbray tra gli autori, poiche' tale signore ha scritto
quello che considero il peggior libro di argomento informatico che io
abbia mai letto, ovvero "Inside Corba : Distributed Object Standards and
Applications".
Ciao,
Nicola

 Applications".
A me il libro non dispiace, ma se ben ricordo non dispiaceva
neanche quel poco di Mowbray che ho letto (non il libro che
citi, ma articoli o columns, mi pare su "Object Magazine" o
giu` di li`).
Chi si trova disturbato da un tono graffiante e provocatorio
non amera` il libro (vedere come "Cause basilari" di una
certa anti-pattern, che so, "Avarizia, Avidita`, Pigrizia", non
e` necessariamente molto "politically correct"... personalmente,
cio` e` parte della ragione per cui apprezzo il libro!).  Lo
stesso per "Pun-tare... FUOCO!... Mi-rare!" e simili, direi,
"anti-slogan", che usano nelle illustrazioni.
Per me, queste cose si sposano alla perfezione col mio stile,
e mi danno esattamente il giusto materiale quando devo
difendere una certa posizione in un meeting -- e nessuno
puo` obiettare, visto che sto solo citando un rispettato libro
di testo, no?-)  Perche` altrimenti, dire al top management
"qui mi pare che la vostra Pigrizia stia avendo il sopravvento
sulla vostra Ignoranza" non passerebbe neppure a me -- ma,
visto che questi sono termini tecnici di software management...:-)
Cio` detto, ci sono molti altri testi sulle parti piu` "soft",
piu` "umane", della gestione dello sviluppo software.  La
maggior parte appaiono scritti da persone con poca comprensione
_aggiornata_ degli aspetti _tecnici_ (spesso mascherata con
erronee asserzioni che gli aspetti tecnici "non contano", o
simili...), e per essere onesto, mi fanno facilmente addormentare.
"Anti-Pattern" e` un'eccezione da questi punti di vista -- gli
autori chiaramente sviluppo ne fanno, E non e` noioso -- quindi
lo apprezzo, forse proprio anche per la sua rarita`!0)
Alex

Quel che descrivi appare interessante, anche per la forma. D'altronde il
libro su Corba che ho citato non mi piace non tanto per una questione di
stile, quanto perche' lo trovo scritto cosi' male sia nella forma che
nei contenuti da ritenerlo sostanzialmente una truffa. Ecco spiegata la
diffidenza...
Ciao,
Nicola Musatti

 e' esattamente una definizione.
Non so bene a quale ti riferisci fra i vari libri che Stroustrup
ha scritto e le loro svariate versioni/edizioni.  A me pare (ma
in questo momento non ho agio di controllare) che 'class
declaration' sia un costrutto come
    class pippo;
(dichiaro che pippo e` una classe ma non definisco come e`
fatta, infatti e` una "incompletely defined type");
e invece 'class definition' il costrutto
    class pippo {
        // ev. contenuti, ovvio
    };
e infatti vista questa pippo NON e` piu` 'incompletely
defined'.
Alex

Sulla separazione tra interfaccia e implementazione in C++ con
particolare riferimento al pattern "Stateless Proxy": ho capito il tuo
punto di vista; continuo a pensare che non abbia solo vantaggi rispetto
al mio.
Sulla separazione tra interfaccia e implementazione in Java rispetto
all'uso degli include: ogni linguaggio di programmazione e' frutto di un
compromesso tra obiettivi ideali e mondo reale. A torto o ragione, il
C++ si trascina dietro scelte legate alla visione del mondo degli anni
Settanta, ma questo ha contribuito indubbiamente al suo successo. Questo
non e' stato per Java (vedi l'assunzione della doppia passata da parte
del compilatore), ma sono stati posti altri obiettivi, legati ad un
modello di computazione adatto al deployment distribuito, che da questo
punto di vista specifico hanno peggiorato le cose. Pero' anche qui la
scelta e' stata determinante per il successo del linguaggio.
Al contrario mi pare che i linguaggi dove, per quanto posso dire, questi
compromessi non sono stati accettati nella stessa misura (mi vengono in
mente Pascal e forse Ada ed Eiffel) hanno avuto successo molto minore.
Sull'esistenza di costrutti che permettano l'identificazione esplicita
dei "componenti": Questo e' un aspetto specifico di un problema piu'
generale; secondo me la tecnologia permetterebbe l'adozione di linguaggi
ricchi da un punto di vista espressivo, ma piu' orientati alla
rappresentazione di algoritmi in quanto tali e meno legati ad un modello
di macchina computazionale di quanto lo siano i linguaggi attuali.
Purtroppo in questo momento non ho tempo di esprimere il mio punto di
vista con il grado di dettaglio necessario a chiarire il mio punto di
vista.
Rispetto a class browser e strumenti analaoghi: tempo addietro ho avuto
una discussione sull'argomento su comp.lang.c++.moderated, dove mi e'
stato segnalato che questi strumenti non sono molto diffusi nelle grosse
aziende informatiche, dove tendenzialmente si preferisce tecniche
"fragili" come le convenzioni di denominazione. Anche qui il problema
potrebbe essere esaminato in dettaglio molto maggiore...
Ricollegandomi al punto precedentemente, potrei probabilmente riuscire a
inventare il linguaggio di programmazione "perfetto" dal mio punto di
vista, ovvero che soddisfa tutti gli obiettivi che a me paiono
importanti e che ottimizza i compromessi tra obiettivi contrastanti. Da
qui a farlo diventare il linguaggio piu' popolare al mondo pero'...
Riguardo all'uso dei termini dichiarazione e definizione di classe: mi
riferisco a "The C++ Programming Language", 3 ed. pag. 225 (la mia e' la
3 ristampa).
Ciao,
Nicola