Newsgroup: it.comp.lang.c++
Titolo: friend e ereditarietà

Mi sono sempre chiesto come mai le classi definite come friend da un'altra
classe non possono essere ereditate mantenendo la stessa proprietą. Esempio
idiota:
class A
{
  int val;
  friend class B;
}
class B
{
  void Init(A& a) { a.val = 10; }
};
class C : public B
{
  void Init(A& a) { a.val = 15; }
}
In questo esempio, la classe C non puņ accedere al membro privato della
classe A, perché questa definisce come friend B ma non C! Questo va un po'
contro i concetti dell'OOP (in particolare al principio di Open-Closed, se
non sbaglio), visto che io dovrei poter "migliorare" la classe B
ereditandola senza per questo modificare la classe A (ad esempio, supponete
che le classi A e B siano forniti in una third-part library, non potrei
farci nulla).
Qualcuno sa spiegarmi il perché di questa "scelta"?
Bye
-----
Giovanni Bajo
Lead Programmer
Prograph Research S.r.l.
http://www.prograph.it

 farci nulla).
Esattamente come non potresti se il componente fosse stato
implementato entro una sola classe.
Le possibilita` di "miglioramento" sono sostanzialmente vincolate
al concetto di override di metodi virtuali; chi progetta la classe
"migliorabile" deve quindi (ed e` uno dei punti chiave della
architettura del componente) determinare esattamente quali
metodi virtuali essa possiede, e con quali vincoli (pre-condizioni,
post-condizioni) essi possono essere sottoposti ad override (il
linguaggio C++ non ha un modo intrinseco di imporre a tempo
di compilazione le pre-condizioni e le post-condizioni, solo la
accessibilita`, ma e` meglio di nulla!-).
Alex

 accessibilita`, ma e` meglio di nulla!-).
Questa secondo me è un'altra gravissima pecca: un sistema di assertion con
pre e post condizioni è quantomeno fondamentale nella scrittura di un
componente per permettere di utilizzare (anche ereditando) il componente in
modo corretto.
Ciao!


 modo corretto.
Purtroppo, il problema di verificare a compile-time asserzioni
non triviali e` insolubile (Turing-completo), nel caso generale,
soprattutto per componenti che siano rilasciati e, insieme,
estendibile (open/closed).  Sather e Eiffel fanno del loro meglio,
ma e` ben lungi dall'essere sufficiente; in pratica, ci si riduce
a test a run-time (che si possono benissimo scrivere anche in
C++, o in Python, ma sono, appunto, run-time, cioe` non
soddisfacenti per un grosso progetto).
Comunque, ti consiglio caldamente di passare (se gia` non l'hai
fatto, e non sei qui solo per disturbare:-) al linguaggio Eiffel (o
a Sather) e fondare un gruppo it.comp.lang.eiffel (se gia` non
esiste) dove potrete dibattere di quello, perche` e` ampiamente
evidente che fra la tua concezione della programmazione ad
oggetti, e quella incorporata nel linguaggio C++, c'e` un
vasto e insondabile oceano di distanza, mentre mi sembri
piu` vicino per vari rispetti all'Eiffel (purtroppo per te mi pare
che Eiffel preveda ancora il concetto di "privato", cioe` che
non aderisca appieno alla tua filosofia, ma forse li potrai anche
convincere:-).
Alex

 convincere:-).
Ehehehe grazie del consiglio. Evidentemente il fatto che io sia cresciuto a
pane e "Object Oriented Software Construction" di Bertrand Meyer ha lasciato
in me più segni di quello che credevo ... e non mi dispiace certo :)
In realtà quello che cerco di fare in effetti è programmare secondo una
filosofia Eiffeleggiante ma in C++, arrivando quindi spesso a scontrarmi con
la struttura di quest'ultimo. Ciò non vuol dire che non stia cercando anche
di imparare filosofia diverse, ed è per questo che sono qui nel newsgroup,
proprio per capire come si programma correttamente in C++.
Ciao


 proprio per capire come si programma correttamente in C++.
Considerando le ore che mi e` costato questo post (compreso saltare
il pranzo, ma a quello ci sono abituato!-), non ho intenzione di investire
molto altro in questa direzione, visto che nel tuo caso non ho la diretta
motivazione di interesse che ho verso il mio collega.
"Come si programma correttamente in C++" e` sfruttando le regole
del linguaggio, e gli strumenti che ti mette a disposizione, piuttosto
che non mugugnandoci contro.
Non c'e` particolare ragione per cui tu dovresti scegliere di cambiare
idea relativamente all'eredita` di friend, alla obbligatorieta` di virtual,
eccetera.  Il C++ e` un linguaggio maledettamente complicato e
sottile, e non privo naturalmente di difetti (visto che si e` evoluto
storicamente, quindi con vincoli di compatibilita`) -- non conosco
linguaggi privi di difetti, ma conosco TANTI linguaggi molto piu`
semplici da imparare e usare al meglio.  Penso, anzi, che il C++
sia usato _troppo_, oggi: che sia usato in tante situazioni dove la
sua potenza spaventosa, il controllo quasi assoluto che da` al
progettista, sono sprecati o addirittura contro-produttivi in quanto
difficili da usare alla perfezione.  A occhio, scommetto che ben
piu` della meta` di quello che oggi si fa in C++ si farebbe meglio
e prima in altri linguaggi.
Essendo tu un "Lead Programmer", sicuramente hai piena scelta
dei linguaggi da usare nei tuoi progetti (se il titolo significa mai
qualcosa).  E allora, il mio consiglio: *esercitala*, quella scelta.
Esercitala scegliendo il linguaggio che cosi` caldamente opini
essere perfetto per i programmi che devi progettare e scrivere.
Se non accetti le scelte filosofiche di fondo del linguaggio che
scegli, non sarai mai pienamente produttivo in quel linguaggio,
e peggio ancora, non sarai mai davvero felice.  Evita l'ulcera.
Usa il linguaggio che e` fatto per te.  Il mondo e` bello perche`
e` vario, e parte di questa varieta` e` che NESSUN linguaggio
di programmazione e` ideale e perfetto per tutti gli usi _E
PER TUTTI GLI UTENTI_.
Alex