Newsgroup: it.comp.lang.c++
Titolo: errata comprensione dell'ereditarietà

segnatura: errore nel tipo di ritorno.
Se il tuo compilatore di da errore, è il compilatore che sbaglia. Il
codice è valido.
Se le funzioni non sono virtuali il problema non c'e'. L'unico problema
lo puoi avere con 
l'alto esempio che avevi postato inizialmente. Rieccolo leggermente
modificato:
class Base1 {
public:
	virtual int funzione() { return 0; }
};
class Base2 {
public:
	virtual void funzione() {}
};
class derivata: public Base1, public Base2 {};
Questo codice è corretto e non deve dare errore. Occhio però che in
derivata (e in tutte 
le classi derivate da essa) NON puoi più ridefinire un membro chiamato
funzione che non prende
alcun parametro. Indipendentemente dal valore di ritorno. Puoi però
lavorare normalmente con
membri chiamati funzione che prendono almeno un parametro.
Dato che non puoi più ridefinire la funzione, ti trovi incasinato se una
(o entrambe) le funzioni
sono virtuali pure. Ovvero:
class Base2 {
public:
	virtual void funzione()=0;
};
class derivata: public Base1, public Base2 {};
Il codice deve compilare senza errori, solo che derivata, così come
anche Base2, sono astratte. 
Quindi non le puoi instanziare. Dato che ne in derivata ne nelle
eventuali classi derivate da essa
puoi ridefinire la funzione pura Base2::funzione() senza avere un
conflitto con Base1::funzione(), di
fatto sia derivata che tutte le classi derivate da essa sono e saranno
sempre e solo astratte. Quindi
non instanziabili. Quindi di fatto inutili.
All'eventuale domanda "come posso derivare sia da Base1 che da Base2
senza trovarmi in questo impiccio?" 
la risposta è questa:
class Base1 {
public:
	virtual int funzione() { return 0; }
	// altri membri
};
class Base2 {
public:
	virtual void funzione()=0;
	// altri membri
};
// voglio derivare sia da Base1 che da Base2. Accetto che funzione() non
sia mai 
// ridefinita dal punto di derivazione in poi. Nella classe derivata (e
successive)
// Base1::funzione() ritorna sempre 0 e Base2::funzione() non fa mai
niente.
// soluzione:
class _nonAbstractBase2: public Base2 {
protected:					
	// protected constructor because this class 
	// MUST be derived, never directly instantiated
	// public interface is abstract 
	_nonAbstractBase2(){}	
 
	// ok protected since Base2::funzione() is
	// the real interface. Could also have been public
	virtual void funzione() {}	
};
class Derivata: public Base1, public _nonAbstractBase2 {};
Nota: nella logica di progettazione la classe _nonAbstractBase2 non
esiste. Il suo
unico scopo è rendere non asratta Base2 nel contesto di derivazione di
Derivata così come
descritto dal commento. Non deve modificare l'interfaccia di Base2 se
non ad uso di Derivata. 
Quindi non deve neppure renderla instanziabile (Base2::funzione si
presume che sia virtuale
pura per qualche motivo). In un certo senso _nonAbstractBase2 fa parte
dell'implementazione
di Derivata. Potrebbe addirittura essere dichiarata come classe privata
all'interno di 
Derivata, salvo che la sintassi del C++ non lo permette dato che
derivata deriva da essa
quindi _nonAbstractBase2 deve essere definita prima di definire
Derivata. Tutti i client esterni
e persino le classi che derivano da Derivata possono ignorare la sua
esistenza e fingere che 
Derivata derivi direttamente da Base2.
-- 
Posted from 
adsl-21-135.38-151.net24.it
 [151.38.135.21] 
via Mailgate.ORG Server - 
http://www.Mailgate.ORG

Ringrazio Andrea Ferro per la spiegazione a riguardo e anche a quella su
delete.
-- 
La classifica dei prodotti MS:
C#, la migliore barzelletta di Bill Gates.
Visual C++, il meno standard dei compilatori C++.
J++, la copiatura più riuscita.
Windows, il più instabile.
Visual Basic, un esempio di prodotto decente della MS - forse l'unico -.
OutlookExpress, scandali su scandali.
La classifica degli "amici" coglioni:
Stefano Zanchi, il miglior lamer del mondo.