/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
C++, dynamic_cast
Fra : Soeren Sandmann


Dato : 05-02-01 20:44

Nedenstående program afvises af g++ med meddelelsen:

storm% c++ -ansi -Wall fest.cc
fest.cc: In function `bool is_orange(Fruit *)':
fest.cc:16: cannot dynamic_cast `fruit' (of type `class Fruit *') to type `class Orange *'

Hvad gør jeg galt?

class Fruit {
public:
Fruit (void) {};
};

class Orange : public Fruit {
public:
Orange (void) {};
};

bool
is_orange (Fruit *fruit)
{
Orange *orange;

orange = dynamic_cast<Orange *>(fruit);
if (orange)
   return true;
else
   return false;
}

int
main (void)
{
return 0;
}

 
 
Igor V. Rafienko (05-02-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 05-02-01 21:02

* Soeren Sandmann
> Nedenstående program afvises af g++ med meddelelsen:
>
> storm% c++ -ansi -Wall fest.cc
> fest.cc: In function `bool is_orange(Fruit *)':
> fest.cc:16: cannot dynamic_cast `fruit' (of type `class Fruit *') to type `class Orange *'
>
> Hvad gør jeg galt?


Glemmer virtuelle funksjoner (CC5.0 forklarer det ganske omstendig, i
motsetning til g++).

dynamic_cast<> kan brukes kun på "polymorphic types". De sistnevnte
får man ved å ha minst en virtuell funksjon. Tradisjonelt sett er
det dtor'en som går i første rekken:


class Fruit
{
public:
Fruit(){}
virtual ~Fruit(){};
};


BTW, hvis du trenger dynamic_cast tyder det ofte på at du har
designproblemer. Du skal i utgangspunktet ikke trenge å vite hvorvidt
du leker med "oranges" eller "fruits" i klientkoden.


> bool
> is_orange (Fruit *fruit)
> {
> Orange *orange;
>
> orange = dynamic_cast<Orange *>(fruit);
> if (orange)
>    return true;
> else
>    return false;
> }


bool
is_orange( const Fruit *fruit )
{
return dynamic_cast< const Orange* >( fruit );
}


but like I said -- tenk deg om før du tar denne ibruk.





ivr, som synes at (void) er en ufyselig vane i C++
--
Besides, meat tends to run away when possible, or fights. Either
response presents behavioral challenges too complex for any existing
robot.
      -- Stuart Wilkinson, inventor of the "gastrobot"

Soeren Sandmann (06-02-2001)
Kommentar
Fra : Soeren Sandmann


Dato : 06-02-01 18:41

igorr@ifi.uio.no (Igor V. Rafienko) writes:

> dynamic_cast<> kan brukes kun på "polymorphic types". De sistnevnte
> får man ved å ha minst en virtuell funksjon. Tradisjonelt sett er

Tak (også til de andre som svarede).

Det er en mærkelig måde at gøre det på. Hvis man ikke ved hvordan
oversætteren kan finde på at repræsentere objekterne, er der absolut
ingen grund til at tro at muligheden for dynamic_cast skulle have
noget at gøre med om der er virtuelle funktioner eller ej.

> BTW, hvis du trenger dynamic_cast tyder det ofte på at du har
> designproblemer. Du skal i utgangspunktet ikke trenge å vite hvorvidt
> du leker med "oranges" eller "fruits" i klientkoden.

Ja, det ved jeg godt. Det er heller ikke fordi jeg er i færd med at
skrive det store frugtstyringsprogram; jeg er bare ved at lære C++.

Christian Worm Morte~ (06-02-2001)
Kommentar
Fra : Christian Worm Morte~


Dato : 06-02-01 18:49

Hej,

> Det er en mærkelig måde at gøre det på. Hvis man ikke ved hvordan
> oversætteren kan finde på at repræsentere objekterne, er der absolut
> ingen grund til at tro at muligheden for dynamic_cast skulle have
> noget at gøre med om der er virtuelle funktioner eller ej.

Grunden er at man f.eks. gerne vil understøtte seperat oversættelse af
kildefilerne. Så man skal kunne oversætte en brug af klassen uden at man
samtidigt behøver kigge på alle de andre steder den bliver brugt.


Venlig Hilsen

Christian Worm



Igor V. Rafienko (07-02-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 07-02-01 12:57

* Christian Worm Mortensen

[snip]

> Grunden er at man f.eks. gerne vil understøtte seperat oversættelse
> af kildefilerne. Så man skal kunne oversætte en brug af klassen uden
> at man samtidigt behøver kigge på alle de andre steder den bliver
> brugt.


Kunne du utdype litt mer?





ivr
--
Besides, meat tends to run away when possible, or fights. Either
response presents behavioral challenges too complex for any existing
robot.
      -- Stuart Wilkinson, inventor of the "gastrobot"

Christian Worm Morte~ (07-02-2001)
Kommentar
Fra : Christian Worm Morte~


Dato : 07-02-01 14:58

Hej,

> > Grunden er at man f.eks. gerne vil understøtte seperat oversættelse
> > af kildefilerne. Så man skal kunne oversætte en brug af klassen uden
> > at man samtidigt behøver kigge på alle de andre steder den bliver
> > brugt.
>
> Kunne du utdype litt mer?

Hvis oversætteren så at sige kun se al koden der skulle udgøre et program på
en gang, så kunne den jo konstatere at der et sted blev brugt dynamic_cast
på Fruit og at den derfor var nødt til at gemme køretids typeinformationer
for Fruit og dens under klasser.

Men hvis man skal understøtte seperat oversættelse af forskellige dele af
programmet kan oversætteren når den oversætter en del jo ikke vide om der i
en anden del bliver brugt dynamic_cast på Fruit.


Venlig Hilsen

Christian Worm



Igor V. Rafienko (07-02-2001)
Kommentar
Fra : Igor V. Rafienko


Dato : 07-02-01 12:56

* Soeren Sandmann

[snip]

> Det er en mærkelig måde at gøre det på.


Det er en begrensning i typecast'en: den skal brukes på klasser og kun
de. Det ville være mer hensiktsmessig å lage en litt mer intelligent
konverteringsfunksjon, men det ble det ikke noe av. ((type) er ikke
helt vellykket).


> Hvis man ikke ved hvordan oversætteren kan finde på at repræsentere
> objekterne, er der absolut ingen grund til at tro at muligheden for
> dynamic_cast skulle have noget at gøre med om der er virtuelle
> funktioner eller ej.


Man trenger ikke å vite hvordan objektene er representert internt for
å vite hva dynamic_cast brukes på:

[quote 5.2.7, p 6]

Otherwise, v shall be a pointer to or an lvalue of a polyporphic type
(10.3)

[/quote]

Man snakker om uttrykket dynamic_cast<T>(v). Definisjonen av
"polymorphic type" er ganske så utvetydig:

[quote 10.3, p 1]

Virtual functions support dynamic binding and object-oriented
programming. A class that declares or inherits a virtual function is
called a polymorphic class.

[/quote]

Og hvis du tror at dette er kompisert, ta et passe hårete uttrykk og
bruk (type) på den. Og så prøv å huske hvilke typecasts vil prøves i
hvilken rekkefølge og hvor portabel effekten blir. En ting er sikkert:
semantikken til typecasts oppfordrer _ikke_ bruken av dem.

[snip]


> Ja, det ved jeg godt. Det er heller ikke fordi jeg er i færd med at
> skrive det store frugtstyringsprogram; jeg er bare ved at lære C++.


Lærdommen er: unngå typecasts :) (forøvrig, det er delvis seriøst
ment)





ivr
--
Besides, meat tends to run away when possible, or fights. Either
response presents behavioral challenges too complex for any existing
robot.
      -- Stuart Wilkinson, inventor of the "gastrobot"

Christian Worm Morte~ (05-02-2001)
Kommentar
Fra : Christian Worm Morte~


Dato : 05-02-01 21:07

Hej

> Nedenstående program afvises af g++ med meddelelsen:
>
> storm% c++ -ansi -Wall fest.cc
> fest.cc: In function `bool is_orange(Fruit *)':
> fest.cc:16: cannot dynamic_cast `fruit' (of type `class Fruit *') to type
`class Orange *'
>
> Hvad gør jeg galt?

En af mine C++ oversættere skriver:

"Type 'Fruit' is not a defined class with virtual functions"

Problemet er formodentlig at en C++ oversætter jo helst skal kunne generere
så effektiv kode som muligt og derfor kan undlade at gemme køretids
typeinformationer for strukturer der ikke har virtuelle metoder. Hvis den
skulle gemme noget ville det jo også pludslig betyde at den ikke kunne
oversætte C programmer lige så effektivt som en C oversætter.


Venlig Hilsen

Christian Worm




Mogens Hansen (05-02-2001)
Kommentar
Fra : Mogens Hansen


Dato : 05-02-01 22:08


"Soeren Sandmann" <sandmann@daimi.au.dk> wrote in message
news:ye8k874difm.fsf@vertigo.daimi.au.dk...
> Nedenstående program afvises af g++ med meddelelsen:
>
> storm% c++ -ansi -Wall fest.cc
> fest.cc: In function `bool is_orange(Fruit *)':
> fest.cc:16: cannot dynamic_cast `fruit' (of type `class Fruit *') to type
`class Orange *'
>
> Hvad gør jeg galt?

"dynamic_cast" fungerer kun sammen med polymofiske klasser - altså sammen
med klasser der har mindst een virtuel metode.
Lav f.eks. en virtuel destructor (den har du sikkert brug for under alle
omstændigheder), og/eller tilføj en virtuel metode som laver det du har brug
for - f.eks. som den "Eatable" som jeg har tilføjet.
Anvendelsen af virtuelle metoder gør iøvrigt ofte anvendelsen af
dynamic_cast overflødig.

class Fruit {
public:
Fruit (void) {};
virtual ~Fruit() {}

virtual bool Eatable(void) const = 0;
};

class Orange : public Fruit {
public:
Orange (void) {};

virtual bool Eatable(void) const
{ return true; }
};

bool
is_orange (Fruit *fruit)
{
return dynamic_cast<Orange *>(fruit);
}

int
main (void)
{
return 0;
}

Venlig hilsen

Mogens Hansen



Søg
Reklame
Statistik
Spørgsmål : 177559
Tips : 31968
Nyheder : 719565
Indlæg : 6408938
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste