Newsgroup: it.comp.lang.c++
Titolo: Problemi con tipo di dato

Salve a tutti! Sto cercando di imparare il C++. Oggi mi sono cimentato
nella classica implementazione dei numeri naturali, reali complessi
etc.
La mia situazione e' questa:
// Console.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
class Naturali
{
public:
  int Dato;
  virtual void Insert(int value){ Dato = abs(value);};
  void Print(void){std::cout << Dato << std::endl;};
};
class Reali : public Naturali
{
public:
  float Dato;
  void Insert(float value){ Dato = value;};
 
 
};
int _tmain(int argc, _TCHAR* argv[])
{
  Naturali nat;
  Reali reali;
  nat.Insert(-10);
  nat.Print();
  reali.Insert(-10.1);
  reali.Print();
	return 0;
}
Non capisco come mai il metodo Print ereditato nella classe Reali
stampa Naturali::Dato e non Reali::Dato... L'unico modo che ho trovato
per stampare Reali::Dato e' stato quello di ridefinire Print
all'interno della classe (metodo a mio parere abbastanza scomodo).
Mi potete dare un suggerimento su come rimediare a questa cosa?
Vi ringrazio in anticipo!

 Vi ringrazio in anticipo!
Escludendo il fatto che non hai presentato codice standard (ma adesso 
non ho voglia di correggerlo), dato che ti aspetti comportamenti diversi 
da Print (nel primo caso stampa un intero, nel secondo un float, e la 
banale omonimia del dato, come capirai, li rende ben poco simili), 
dovrai definire i due diversi comportamenti (ricordati che, sebbene la 
sintassi sia la stessa, i metodi chiamati per la stampa, sono diversi).
-- 
Mat/tia Belletti - Undergraduate student @ 
cs.unibo.it
ICQ: 33292311    - email: 
mbel...@cs.unibo.it
IRC: RedGlow     - site(s): 
http://www.cs.unibo.it/~mbellett
Linux registered user 299762 @ Linux registered machine 213003

 dovrai definire i due diversi comportamenti
Ok, fin qui ci siamo. Ma il mio dubbio riguardava il fatto che ci
fossero sia Naturali::Dato e Reali::Dato all'interno della classe
derivata. Io ero convinto che la ridefinizione annullasse il tipo di
dato originario per sostituirlo con quello ridefinito.

 Mi potete dare un suggerimento su come rimediare a questa cosa?
Assolutamente no!
Perché è letteralmente un abominio pretendere che
una funzione stampi un valore in base al suo nome
simbolico e non all'eredità di funzioni.
Il fatto che "nella realtà" l'insieme dei Naturali sia
immerso nell'insieme dei Reali non dovrebbe portarti
a far derivare una classe dall'altra (cosa che per altro
in un calcolatore non ha senso dato che il concetto di
numero reale o naturale non esiste e soprattutto NON sono
uno il sovrainsieme dell'altro): la derivazione e le
funzioni virtuali danno la possibilità di ridefinire
una funzione proprio per quello che vorresti fare tu.
Prova a pensare una soluzione in termini di derivazione
da una classe pura, magari come esercizio (non ho detto
che *è* la soluzione, è un possibile soluzione...).
SiMoStro

Ma scusa secondo il tuo ragionamento: i naturali sono un sottoinsieme dei
reali, quindi semmai dovresti derivare la classe Naturali dai Reali e non
viceversa. A questo punto se vuoi definire una classe Print() in Reali che
và bene per entrambi devi definire Dato il più generale possibile ossia
float (e non ridefinirlo anche in Naturali, altrimenti devi per forza
ridefinire anche Print() perchè int Dato non sovrascrive float Dato, poichè
non esistono in c++ membri virtuali!)
class Reali
{
public:
float Dato;
virtual void Insert(float value){ Dato = value;};
void Print(void){std::cout << Dato << std::endl;};
};
class Naturali:public Reali
{
public:
void Insert(int value){ Dato = abs(value);}; << lo trasforma comunque in un
int!
};

 dato originario per sostituirlo con quello ridefinito.
assolutamente no. La classe derivata contiene tutti i membri dato delle 
classi base, più naturalmente quelli propri (eccezion fatta per 
l'ereditarietà di tipo "virtual", ma non è questo il caso).
-- 
Son capaci tutti di dire "ti amo tanto" mentre stan facendo l'amore...

 l'ereditarietà di tipo "virtual", ma non è questo il caso).
Veramente i membri ci sono tutti anche se si eredita in modo virtuale.
Ciao,
Nicola

 Salve a tutti! Sto cercando di imparare il C++...
Mi sbagliero', ma dalle domande che poni ho la sensazione che tu stia
cercando di imparare per tentativi. Il C++ e' un linguaggio troppo
complesso per procedere in questo modo. Ti conviene procurarti un buon
libro e cominciare a studiare un po' prima di cimentarti.
Altrimenti orientati ad un linguaggio piu' semplice.
Ciao,
Nicola

cercando di imparare per tentativi.
Piu' che altro sono stato troppo precipitoso su alcuni argomenti e
quindi mi sa che ho dato per scontato alcune cose. Prendero' atto dei
vari suggerimenti (grazie a tutti) e tornero' indietro di qualche
capitolo!

Nicola Musatti wrote:

ereditando in maniera virtuale se D è una sottoclasse di B e C ed, a 
loro volta, entrambe sono sottoclassi di A ed A contiene il membro dato 
_dato, D conterrà una sola variabile membro _dato e non due, come 
succederebbe se non avessimo utilizzato l'ereditarietà "virtual".. un 
po' contorto ma mi sembra corretto. No?


 po' contorto ma mi sembra corretto. No?
Questo e' corretto, ma non e' in contraddizione con l'affermazione
originale. Nel caso dell'eredita' virtuale un membro dato della classe
base e' membro contemporaneamente di due sottoclassi indipendenti tra
loro. Dal punto di vista concettuale e' come se fosse membro due volte
della classe piu' derivata.
Ciao,
Nicola

 
Ok.. giusto per capire se in realtà non avessi capito niente 
dell'ereditarità virtuale (ipotesi più che plausibile)!


 capitolo!
Eh eh! Hai sottovalutato il problema...
Per imparare bene in C++ occorrono parecchie settimana di serio lavoro...
(penso ad una persona che non è proprio a digiuno di programmazione ed è
mediamente dotata). Poi c'è chi ci mette molto meno o anche molto di più! In
ogni caso, non saltare i capitoli... Tutto diventa importante quando sei
solo ad affrontare il tuo problema di sviluppo e non hai più un esempio sul
libro da seguire. Ma a questo punto potrai sicuramente domandare alle
persone esperte di questo NG, quando sarai in difficoltà.
P.S.
Una cosa, quando chiedi a questo NG assicurati che la tua domanda sia
focalizzata sullo standard C++.
Quell'include sul tuo codice non va ad includere (ad esempio) codice comune
a tutti i compilatori.
Questo non significa che non puoi usare librerie/framework commerciali (es.
MFC).
Non significa che, se hai comunque problemi su aspetti generali del tuo
codice che pur gira su ambienti e compilatori propietari tu non possa
chiedere, ma attento a non fare come alcuni che poi ti chiedono su classi o
aspetti che nulla hanno a che vedere con lo standard C++ trattato su questo
NG.
E' anche importante all'inizio del tuo percorso (di studente, in relazione
al C++) capire la differenza fra C++ standard e altre librerie/framework, e
capirne l'importanza (la piena portabilità, ad esempio) dello sviluppo
secondo standard.
Molti che cominciano a studiare il C++ rimangono disorientati quando
capiscono che non possono aprire finestre o creare animazioni a video o
effetti speciali, ma è fondamentale secondo me, cominciare proprio da questo
punto per riuscire poi a risolvere i problemi al computer. Aprire una
finestra non è un problema, è questione di tecnica (propria di ogni S.O. o
quasi... e quando vorrai farlo basterà fare qualche scelta e documentarsi
opportunamente...) per scrivere un programma che risolve problemi complessi
invece, non è un S.O. specifico che ci aiuta!!
Questo comunque è solo il mio modesto consiglio...
ciao e in bocca al lupo.
Paolo Ferraresi.