Newsgroup: it.comp.lang.c++
Titolo: casting (lo so che non e' bello...)

Ho un problema sul casting:
Mettiamo che abbia definito una classe Point tipo:
class Point {
    private:
        int x,y;
    public:
        ...
        Point operator+(const Point & p0) { return Point(x+p0.x,y+p0.y); }
};
Poi voglio derivare una classe Point3d:
class Point3d: public Point{
    private:
        int z;
    public:
        ...
        Point3d operator+(const Point3d &);
}
Come posso fare a fare la somma di due Point3d senza poter accedere ad x e y
del Point da cui la classe e' derivata?
L'unico modo penso che sia quello di fare un cast, ed usare l'operator+ del
Point.
Point3d Point3d::operator+(const Point3d & p0){
    Point3d temp;    //viene inizializzato a 0
    //(Point) temp= Point::operator+((Point) p0);  //cosi' non funziona
    // temp= (Point3d) Point::operator+((Point) p0);  //cosi' nemmeno
    temp.z = this->z + p0.z;
    return temp;
}
Nel primo caso non succede nulla, benche' non mi dia errori, le coordinate x
e y di temp rimangono 0.
Nel secondo caso, mi dice che non capisce che costruttore deve usare, ma io
volevo semplicemente che mi facesse il casting, non che usasse un
costruttore!
Non capisco perche' non vada bene...
Zeppe

 ha scritto nel messaggio
news:a7pnto$qmh$1...@pegasus.tiscalinet.it...

(approccio minimalista)
con protected: al posto di private: i valori x e y sono visibili anche dalla
classe derivata.
(volendo evitare protected: ma anche con esso)
tre funzioni  inline get_x(), get_y(), get_z() che leggano i valori.
Non vedo alcuna ragione di rendere inaccessibili in lettura tali valori.
----
Sergio Bianchi

 Non vedo alcuna ragione di rendere inaccessibili in lettura tali valori.
Beh, lo so che l'esempio e' stupido, sicuramente sarebbe banale mettere x e
y protected, che e' la cosa piu' ovvia, e faciliterebbe molto le cose. Ma
non potendo toccare la class Point, che non ha funzioni che consentono di
accedere direttamente alle coordinate del punto, ma ha la funzione somma,
non si potrebbe fare lo stesso con un casting?
Una funzione get_x() in Point non c'e', in Point3d non potrei averla...
Zeppe

 ha scritto nel messaggio
news:a7qooh$u1a$1...@pegasus.tiscalinet.it...

Da :
class Point {
    private:
        int x,y;
    public:
        ...
        Point operator+(const Point & p0) { return Point(x+p0.x,y+p0.y); }
};
deduco l' esistenza di un costruttore Point(int vx,  int vy);
ma non ci hai detto nulla sui costruttori di Point3d.
class Point3d: public Point{
    private:
        int z;
    public:
        ...
        Point3d operator+(const Point3d &);
}
Supponiamo che esista:  Point3d(int vx,  int vy,  int vz ) : Point(vx, vy),
z(vz) {  }
Il fatto di potere creare punti ma di non poterne leggere le coordinate
(singolare esempio di Write Only Memory)  fa si che noi possiamo sommare le
coordinate dei punti ma non riusciremo mai ad estrarle per passarle al
costruttore Point(int vx,  int vy).
Neppure Point operator+(const Point & p0) ci viene in aiuto in quanto non
modifica lo stato dell' oggetto Point3d casted ma crea un nuovo Point ancora
blindato.
Supponiamo che esista un costruttore copia Point(const Point& ).
In questo caso occorrerà definire un nuovo costruttore Point3d(const Point&
a2dpoint,  int vz ) : Point(a2dpoint),  z(vz) {  }
da cui
 Point3d operator+(const Point3d &  a3dpoint)
{
     return Point3d(Point::operator+(static_cast<const Point&>(a3dpoint)), z
+ a3dpoint.z);
}
Non ho altre idee se non accessi poco ortodossi alle varibili private.
----
Sergio Bianchi

 x e y del Point da cui la classe e' derivata?
utilizzando "protected" al posto di "private" per designare il campo di 
visibilita` di x e y.
Considera pero` che IMHO e` una pessima idea derivare Point3d da Point: 
l'ereditarieta` pubblica modella una relazione di tipo IS-A: in pratica 
derivando tu affermi: "Point3d e` una versione 'aggiornata' di Point, 
con alcune funzionalita` in piu`: potete tranquillamente usare un 
Point3d ovunque avreste potuto usare un Point".
Ovviamente questa frase non ha senso: un Point3d IS-NOT-A Point; supponi 
di avere questa funzione:
Rect passante_per_due_punti(Point, Point);
Credi che abbia senso una chiamata del genere?:
Point a;
Point3d b;
Rect r = passante_per_due_punti(a,b);
Quale e` la retta passante per un punto bidimensionale e uno 
tridimensionale???
Il mio consiglio e` lasciare perdere l'ereditarieta` pubblica in questo 
caso.
ciao Anto
-- 
Antonio Cuni, 19 anni, studente
Brainbench C++ Master: 4.73, higher than 99% of all previous test takers.
C Language: 3.79, higher than 92% of all previous test takers.
Guida C/C++ di Programmazione.it: 
http://cpp.programmazione.it

 Considera pero` che IMHO e` una pessima idea derivare Point3d da Point:
Sono d'accordissimo con te!! Anche imho e' assolutamente inutile, ma il
fatto e' che il professore ha scelto questo esempio per mostrarci l'eredita'
in c++, quindi ho voluto forzare la cosa. In effetti anche la scelta delle x
e y private e' "forzata", nel senso che volevo provare a fare il cast...
Diciamo che questo e' solo un esercizio inutilmente complesso...
Zeppe

 }
Ok, grazie, questo funziona correttamente! Piuttosto, cosa vuol dire
static_cast? C'e' differenza col cast c-style?
Zeppe


....
static_cast
dynamic_cast
const_cast
reinterpret_cast
sono costrutti introdotti in c++ per controllare e meglio esplicitare il
tipo di conversione che si desidera ottenere.
Fai riferimento ad un manuale o all' help del tuo compilatore per la
completa definizione di questi operatori.
il cast c-style opera secondo uno di questi metodi in funzione della
situazione.
Cio può portare a fraintendimenti ,conversioni ambigue e problemi di
portabilità. Ne è pertanto scoraggiato l' uso.
----
Sergio Bianchi

 l'eredita' in c++, 
fa i complimenti al tuo prof...


Credi che abbia senso una chiamata del genere?:
Perche' no ? se parli di "senso" ha senso, ma bisogna vedere
come viene implementato.  Cosi' come lo implementi tu e'
ovviamente errato.  Ma, concettualmente, una retta passa per
due punti sia che si trovino nello spazio, sia che si
trovino nel piano.  
-- 
Andrea Laforgia (
walkie...@libero.it
)
"Usenet is a strange place" [Dennis Ritchie]

 distanza tra punti, calcolo della retta passante). 
si, ma l'OP parlava di Point3D derivato da Point2D, non Point generico...
e questo e' IMHO errato.
il tuo esempio invece non fa una grinza.
-- 
Ciao by Allanon
Q: Why do programmers always mix up Christmas and Halloween?
A: Because 25 Dec = 31 Oct

 e questo e' IMHO errato.
Giusto, e' che ho letto "Point" nel messaggio originale e non
"Point2D", per cui pensavo si trattasse di un punto generico.
-- 
Posted via Mailgate.ORG Server - 
http://www.Mailgate.ORG

 modifica.
No. Se provi a compilare codice del genere con g++ ottieni un messaggio 
piuttosto chiaro:
ISO C++ forbids cast to non-reference type used as lvalue


 ha scritto nel messaggio
news:a81r70$3b1$2...@newsreader.mailgate.org...

D' accordo , ma per quei compilatori che compilano (Borland C++ Builder 6.0)
che interpretazione ne diamo ?
Point3d a(9,9,9);
   push 9
   push 9
   push 9
   lea eax,dword ptr [ebp-64]
   push eax
   call @@Point3d@$bctr$qiii
   add esp,16
 Point3d b(4,4,4);
   push 4
   push 4
   push 4
   lea edx,dword ptr [ebp-80]
   push edx
   call @@Point3d@$bctr$qiii
   add esp,16
 (Point) a = (Point) b;
    mov ecx,dword ptr [ebp-64]
    mov dword ptr [ebp-36],ecx
    mov eax,dword ptr [ebp-60]
    mov dword ptr [ebp-32],eax
    mov edx,dword ptr [ebp-80]
    mov dword ptr [ebp-48],edx
    mov ecx,dword ptr [ebp-76]
    mov dword ptr [ebp-44],ecx
    mov eax,dword ptr [ebp-48]
    mov dword ptr [ebp-36],eax
    mov eax,dword ptr [ebp-44]
    mov dword ptr [ebp-32],eax
 a = b;
    mov edx,dword ptr [ebp-80]
    mov dword ptr [ebp-64],edx
    mov edx,dword ptr [ebp-76]
    mov dword ptr [ebp-60],edx
    mov edx,dword ptr [ebp-72]
    mov dword ptr [ebp-56],edx
----
Sergio Bianchi

 spazio non e' un punto ? A mio avviso e' sbagliato.
ti ha gia` risposto Allanon; l'OP usava una classe di nome Point che 
pero` incapsulava il concetto di Point2d.


 6.0) che interpretazione ne diamo ?
che non sono standard.
