Newsgroup: it.comp.lang.c++
Titolo: static o private?

Usando il solito schema classe.h+classe.cpp per una classe, vi è mai 
capitato di chiedervi se dichiarare una funzione locale al file.cpp 
oppure privata?
Kiuhnm


Si. Capita abbastanza frequentemente in grandi classi di notare che c'e' 
(o ci sarebbe) del codice duplicato che non accede ai membri 
dell'oggetto. Per fattorizzare tale codice, si puo' creare un'apposita 
routine statica.
Se tale routine non sembra utile al di fuori della classe stessa, e non 
viene mai richiamata dal corpo delle funzioni inline la si puo' 
dichiarare sia come membro privato static della classe, che come 
funzione globale static nel file di implementazione.
Nei linguaggi object-oriented puri questa seconda opzione non esiste, ma 
in C++ esiste in quanto linguaggio ibrido.
Io preferisco questa opzione in quanto:
* Solo in questo modo la funzione risulta invisibile al linker.
* Solo in questo modo il cambio della firma della funzione, non provoca 
una ricompilazione di tutti i moduli che usano questa classe.
Se non e' una funzione inline, all'inizio del file di implementazione 
metto il prototipo della funzione, e in un punto qualunque del corpo del 
file metto la definizione della funzione.
Se invece e' una funzione inline, all'inizio del file di implementazione 
metto la definizione della funzione, senza prototipo.
-- 
     Carlo Milanesi
 
http://digilander.libero.it/carlmila

 metto la definizione della funzione, senza prototipo.
Ora che ci penso (farà piacere a Soviet_Mario) questa è un'occasione 
nella quale mi potrei addirittura sognare di includere un file 
"details.cpp" contenente le ingombranti funzioni static.
No, scherzo, scherzo...
Kiuhnm

 Esisterebbero i namespace anonimi
I namespace anonimi non nascondono realmente le funzioni al linker; si 
limitano a decorarle in modo univoco.


 Kiuhnm

 limitano a decorarle in modo univoco.
Questo me l'hai già detto, ma in pratica il risultato non cambia di 
molto. La battuta alludeva al fatto che il "birthday paradox" potrebbe 
giocare contro di noi, in casi veramente particolari e comunque improbabili.
Kiuhnm

 dubbi al riguardo li ho ancora).
Non ti ho risposto perché non ho niente di particolarmente intelligente 
da dirti.
In questo caso particolare, ha senso includere un file cpp B in un file 
cpp A perché si vuole che le funzioni siano locali rispetto ad A. 
Ovviamente /solo/ A va compilato direttamente.
Direi che, in generale, è consigliato includere file cpp solo se vi è un 
motivo ben preciso (come in questo caso). Non va preso come modello 
perché distrugge completamente la compilazione modulare.
Gli header precompilati servono a salvare tempo quando più file cpp 
includono gli stessi header, ma se uno di questi header viene 
modificato, si ha ugualmente una ricompilazione di parecchio codice.
Lo stesso accadrebbe con l'inclusione di file cpp. Modificare il primo 
file incluso richiederebbe una ricompilazione di tutti gli altri, mentre 
nel caso usuale, cioè usando file separati, questo non avverrebbe.
Non vedo grandi vantaggi, insomma. Tecnicamente si potrebbe dire che 
creeresti delle false dipendenze che rallenterebbero il tempo 
complessivo di compilazione.
Se l'intellisense non funziona, buttalo.
Quello del Visual C++ 2005 non mi dà particolari problemi. Ovviamente il 
codice sul quale lavori deve essere abbastanza corretto altrimenti 
l'intellisense non può funzionare correttamente.
Kiuhnm

 routine statica.
Mi attacco qui, anche se riguarda più la OOP che il C++, per chiedere 
lumi su un dubbio che ho da tempo: qual'è il "posto adatto" per le 
funzioni "utility" che svolgono piccoli compiti utili a più classi ma 
specifici di nessuna in particolare? Io di solito le lascio "sfuse" in 
un file "attrezzi.cpp", perchè fare una classe apposta non mi pare che 
porti vantaggi.
Ma è un errore, dal punto di vista della OOP? Voglio dire, questo è un 
problema aperto della OOP oppure deriva da una (mia) errata modellazione 
del sistema di classi, che se fatta bene invece non dovrebbe lasciare "a 
piedi" queste funzioncine?

 piedi" queste funzioncine?
Non rispondo alla domanda, ma penso che l'OOP sia una boa, non la 
destinazione.
Da SICP di Abelson & Sussman:
Developing a useful, general framework for expressing the relations 
among different types of entities (what philosophers call ``ontology'') 
seems intractably difficult. The main difference between the confusion 
that existed ten years ago and the confusion that exists now is that now
a variety of inadequate ontological theories have been embodied in a 
plethora of correspondingly inadequate programming languages. For 
example, much of the complexity of object-oriented programming languages 
-- and the subtle and confusing differences among contemporary 
object-oriented languages -- centers on the treatment of generic 
operations on interrelated types. Our own discussion of computational 
objects in chapter 3 avoids these issues entirely. Readers familiar with 
object-oriented programming will notice that we have much to say in 
chapter 3 about local state, but we do not even mention ``classes'' or 
``inheritance.'' In fact, we suspect that these problems cannot be 
adequately addressed in terms of computer-language design alone, without 
also drawing on work in knowledge representation and automated reasoning.
Kiuhnm

 also drawing on work in knowledge representation and automated reasoning.
Vale a dire che l'unico in grado di strutturare correttamente ad oggetti 
un programma saranno... i computer stessi, quando avranno raggiunto 
l'autocoscienza e saranno in grado di programmarsi da soli. Questo SI' 
che è deprimente... quasi quasi vado a farmi insegnare come si coltivano 
le patate... :-|

 Kiuhnm

 qualcosa nei settaggi dell'ambiente o non so che altro
Prova a eliminare i file .ncb relativi al tuo progetto.
In tal modo l'intellisense ricostruirà il database.
Kiuhnm

 No, scherzo, scherzo...
Una pratica piu' ragionevole e' quella di identificare tali file con
un'estensione distinta. La piu' comunemente usata e' '.ipp'.
Ciao,
Nicola

 piedi" queste funzioncine?
Al contrario direi che questo problema mette in evidenza un limite
dell'OOP dura e pura. Tra parentesi non e' un caso che i linguaggi OO
"derivati" dal C++ si stiano tutti dotando di meccanismi di
programmazione generica, che quando sono riusciti sono ortogonali
all'approccio ad oggetti.
Cio' che mantiene il C++ migliore dei suoi discendenti e' proprio il
fatto che ti permette di rappresentare tutti gli elementi della tua
soluzione in modo naturale, senza forzarti all'interno di strutture che
in taluni casi sono del tutto fini a loro stesse.
Ciao,
Nicola

 all'approccio ad oggetti.
Cosa vuoi dire con "ortogonale" in questo contesto?
1) o si usa la OOP o si usa la programmazione generica (ma dai!!)
2) si possono usare entrambe contemporaneamente e in modo del tutto 
indipendente l'una dall'altra (mi sembra normale che sia cosě...)

 indipendente l'una dall'altra (mi sembra normale che sia così...)
Non è così scontato.
Kiuhnm

 Cosa vuoi dire con "ortogonale" in questo contesto?
Che la definizione dei meccanismi di programmazione generica e' del
tutto indipendente da quella dei meccanismi di OOP, a differenza ad
esempio di Java dove e' subordinata.
Ad esempio:
- Non e' necessaria una relazione tra i tipi che possono essere usati
come
  argomenti di un template;
- Posso definire template di funzioni libere.
Ciao,
Nicola

 
Ma tu hai progetti in cui usi 23 compilatori C++ contemporaneamente? :-)

 Ma tu hai progetti in cui usi 23 compilatori C++ contemporaneamente? :-)
Magari uno sviluppa cross-platform. O vuole che due major version di gcc
facciano la stessa cosa :)
-- 
blog:  
http://www.akropolix.net/rik0/blogs
 | Uccidete i filosofi,
site:  
http://www.akropolix.net/rik0/
      | tenetevi riso e
forum: 
http://www.akropolix.net/forum/
     | bacchette per voi.

 facciano la stessa cosa :)
Warning: Mission Impossibile ;-P

 Warning: Mission Impossibile ;-P
È che sono di recente infuriato con alcune librerie "scientifiche" che
compilano con il 3 o con il 4 o con il 4.0.1 ma non il 4.0.0 etc... 
O meglio, compilare compilano, poi i test fanno quello che vogliono.
Mi sono come dire, lasciato prendere :)
