Programmieren - alles kontrollieren 4.941 Themen, 20.715 Beiträge

c++: problem mit dynamic_cast.... funktioniert dieses programm b

Yves3 / 8 Antworten / Baumansicht Nickles

halo


ich hab eine code aus meinem buch. beim kompillieren mit visual studio 6.0 gibt es eine warnung.


warning C4541: 'dynamic_cast' fuer polymorphen Typ 'class Mammal' mit /GR- verwendet; unvorhersehbares Verhalten moeglich


bei meinem kollegen gibt es die selbe warnung. (leider auch visual studio 6.0) das programm stürzt dann nach der dritten eingabe ab. :-(


könntet ihr mal schauen, ob das programm bei euch auch abstürzt?(wenn möglich mit einem anderen kompiller) oder noch besser: wisst ihr, woran das liegt?


danke!


// Listing 18.2 - Dynamische Typumwandlung
#include <iostream.h>
class Mammal
{
  public:
 Mammal():itsAge(1) { cout << "Mammal-Konstruktor...\n"; }
 ~Mammal() { cout << "Mammal-Destruktor...\n"; }
 virtual void Speak() const { cout << "Mammal gib Laut!\n"; }
  protected:
 int itsAge;
};


class Cat: public Mammal
{
  public:
 Cat() { cout << "Cat-Konstruktor...\n"; }
 ~Cat() { cout << "Cat-Destruktor...\n"; }
 void Speak()const { cout << "Miau\n"; }
 void Purr() const { cout << "rrrrrrrrrrr\n"; }
};


class Dog: public Mammal
{
  public:
 Dog() { cout << "Dog-Konstruktor...\n"; }
 ~Dog() { cout << "Dog-Destruktor...\n"; }
 void Speak()const { cout << "Wuff!\n"; }
};



int main()
{
 const int NumberMammals = 3;
 Mammal* Zoo[NumberMammals];
 Mammal* pMammal;
 int choice,i;
 for (i=0; i<NumberMammals; i++)
 {
  cout << "(1)Hund (2)Katze: ";
  cin >> choice;
  if (choice == 1)
   pMammal = new Dog;
  else
   pMammal = new Cat;


  Zoo[i] = pMammal;
 }


 cout << "\n";


 for (i=0; i<NumberMammals; i++)
 {
  Zoo[i] ->Speak();


  Cat *pRealCat = 0;
  pRealCat = dynamic_cast< Cat *> (Zoo[i]);


  if (pRealCat)
   pRealCat->Purr();
  else
   cout << "Oh nein, keine Katze!\n";


  delete Zoo[i];
  cout << "\n";
 }


 return 0;
}

bei Antwort benachrichtigen
Yves3 Nachtrag zu: „c++: problem mit dynamic_cast.... funktioniert dieses programm b“
Optionen

ich hab noch vergessen:
tippfehler sind ausgeschlossen. als es das erste mal nicht funktionierte, kopierte ich den code von der buch-cd.

bei Antwort benachrichtigen
d-oli Yves3 „c++: problem mit dynamic_cast.... funktioniert dieses programm b“
Optionen

Hi,

Habe das mit "gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)" und "GNU Make version 3.79.1, built for i386-redhat-linux-gnu" kompilliert und gelinkt.

C++ Source
**************


// Listing 18.2 - Dynamische Typumwandlung
#include <iostream.h>

class Mammal
{
public:
Mammal():itsAge(
1) { cout << "Mammal-Konstruktor...\n"; }
~Mammal() { cout <<
"Mammal-Destruktor...\n"; }

virtual
void Speak() const { cout << "Mammal gib Laut!\n"; }

protected:
int itsAge;
};

class Cat: public Mammal
{
public:
Cat () { cout <<
"Cat-Konstruktor...\n"; }
~Cat() { cout <<
"Cat-Destruktor...\n"; }

void Speak()const { cout << "Miau\n"; }
void Purr() const { cout << "rrrrrrrrrrr\n"; }
};

class Dog: public Mammal
{
public:
Dog () { cout <<
"Dog-Konstruktor...\n"; }
~Dog() { cout <<
"Dog-Destruktor...\n"; }

void Speak()const { cout << "Wuff!\n"; }
};

int main()
{
const int NumberMammals = 3;
Mammal* Zoo[ NumberMammals ];
Mammal* pMammal;
int choice, i;

for( i=
0; i<NumberMammals; i++ )
{
cout <<
"(1)Hund (2)Katze: ";
cin >> choice;
if( choice ==
1 )
{
pMammal = new Dog;
}
else
{
pMammal = new Cat;
}
Zoo[i] = pMammal;
}

cout <<
"\n";

for( i=
0; i<NumberMammals; i++ )
{
Zoo[ i ]->Speak();
Cat *pRealCat =
0;
pRealCat = dynamic_cast< Cat * > ( Zoo[ i ] );

if( pRealCat )
{
pRealCat->Purr();
}
else
{
cout <<
"Oh nein, keine Katze!\n";
}

delete Zoo[ i ];
cout <<
"\n";
}

return
0;
}


Makefile Source:
*******************


CXX = g++
LDFLAGS = -g -pedantic -W -Wall
PGNAME = mammal

.PHONY: all clean

all: mammal

mammal.o: mammal.cpp
$(CXX) -O2 -c mammal.cpp

mammal: mammal.o
$(CXX) -o $(PGNAME) $(LDFLAGS) mammal.o

clean:
rm -f *.o
rm -f
$(PGNAME)




Ausgabe make:
******************
$ make
g++ -O2 -c mammal.cpp
In file included from /usr/include/c++/3.2.2/backward/iostream.h:31,
from mammal.cpp:2:
/usr/include/c++/3.2.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the
Konstruktive Kritik zeichnet sich dadurch aus, dass sie höflich, nützlich und sachlich ist.
bei Antwort benachrichtigen
d-oli Yves3 „c++: problem mit dynamic_cast.... funktioniert dieses programm b“
Optionen

Hi,

Habe das mit "gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)" und "GNU Make version 3.79.1, built for i386-redhat-linux-gnu" kompilliert und gelinkt.

C++ Source
**************


// Listing 18.2 - Dynamische Typumwandlung
#include <iostream.h>

class Mammal
{
public:
Mammal():itsAge(
1) { cout << "Mammal-Konstruktor...\n"; }
~Mammal() { cout <<
"Mammal-Destruktor...\n"; }

virtual
void Speak() const { cout << "Mammal gib Laut!\n"; }

protected:
int itsAge;
};

class Cat: public Mammal
{
public:
Cat () { cout <<
"Cat-Konstruktor...\n"; }
~Cat() { cout <<
"Cat-Destruktor...\n"; }

void Speak()const { cout << "Miau\n"; }
void Purr() const { cout << "rrrrrrrrrrr\n"; }
};

class Dog: public Mammal
{
public:
Dog () { cout <<
"Dog-Konstruktor...\n"; }
~Dog() { cout <<
"Dog-Destruktor...\n"; }

void Speak()const { cout << "Wuff!\n"; }
};

int main()
{
const int NumberMammals = 3;
Mammal* Zoo[ NumberMammals ];
Mammal* pMammal;
int choice, i;

for( i=
0; i<NumberMammals; i++ )
{
cout <<
"(1)Hund (2)Katze: ";
cin >> choice;
if( choice ==
1 )
{
pMammal = new Dog;
}
else
{
pMammal = new Cat;
}
Zoo[i] = pMammal;
}

cout <<
"\n";

for( i=
0; i<NumberMammals; i++ )
{
Zoo[ i ]->Speak();
Cat *pRealCat =
0;
pRealCat = dynamic_cast< Cat * > ( Zoo[ i ] );

if( pRealCat )
{
pRealCat->Purr();
}
else
{
cout <<
"Oh nein, keine Katze!\n";
}

delete Zoo[ i ];
cout <<
"\n";
}

return
0;
}


Makefile Source:
*******************


CXX = g++
LDFLAGS = -g -pedantic -W -Wall
PGNAME = mammal

.PHONY: all clean

all: mammal

mammal.o: mammal.cpp
$(CXX) -O2 -c mammal.cpp

mammal: mammal.o
$(CXX) -o $(PGNAME) $(LDFLAGS) mammal.o

clean:
rm -f *.o
rm -f
$(PGNAME)




Ausgabe make:
******************
$ make
g++ -O2 -c mammal.cpp
In file included from /usr/include/c++/3.2.2/backward/iostream.h:31,
from mammal.cpp:2:
/usr/include/c++/3.2.2/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the
Konstruktive Kritik zeichnet sich dadurch aus, dass sie höflich, nützlich und sachlich ist.
bei Antwort benachrichtigen
Yves3 d-oli „Hi, Habe das mit gcc version 3.2.2 20030222 Red Hat Linux 3.2.2-5 und GNU Make...“
Optionen

die speak methoden der abgeleiteten klassen sind jetzt auch "virtual".

leider kapier ich nicht ganz, was du damit meinst:
"#include iostream anstelle von iostream.h verwenden und dann using namespace std; oder std::cout std::cin etc."
sorry, ich hab noch nicht so viel erfahrung beim programmieren.

dein kompiller sagt, dass der code teilweise veraltet ist. weist du welcher teil?

ich werde jetz auch linux installieren und mal den kompiller probieren. das hatte ich eh schon lange vor. visual studio ist ja nicht gerade ein ansi c++ compiller, eher ms c++ ;-).




bei Antwort benachrichtigen
d-oli Yves3 „die speak methoden der abgeleiteten klassen sind jetzt auch virtual . leider...“
Optionen



> die speak methoden der abgeleiteten klassen sind jetzt auch "virtual".
heisst das, dass es jetzt funktioniert wäre interessant zu wissen.
wäre nämlich eine weitere vc6 spezial eigenschaft die wichtig zu wissen wäre.

>
leider kapier ich nicht ganz, was du damit meinst:
>
"#include iostream anstelle von iostream.h verwenden und dann using namespace std; oder
> std::cout std::cin etc."
> sorry, ich hab noch nicht so viel erfahrung beim programmieren.
anstelle von #include <iostream.h> verwendest du neu <iostream>.
da sich cout, cin und endl etc. gemäss neuem c++ standard nicht
mehr im globalen sondern im std namensbereich befinden
, muss du
auf einer neuen Zeile noch
using namespace std; oder vor jedem cout,
cin oder endl noch ein std:: einfügen.

So:

// alter c++ standard
#include <iostream.h>

int main()
{
cout << "Hallo, Welt!" <<endl;
return 0;
}

// neuer c++ standard
#include <iostream>
using namespace std;

int main()
{
cout << "Hallo, Welt!" << endl;
return 0;
}
// … oder
#include <iostream>

int main()
{
std::cout << "Hallo, Welt!" << std::endl;
}

// … oder
#include <iostream>
std::cout;
std::endl,

int main()
{
cout << "Hallo, Welt!" << endl;
return 0;
}
>
dein kompiller sagt, dass der code teilweise veraltet ist. weist du welcher teil?
ja. <iostream.h>. redhat hat das auftretende name space problem sehr schön mit einem
zus
ätzlichen header file gelöst. dort sind ale std::<was auch immer> aufgeführt und
es erscheint eine meldung
.

>
visual studio ist ja nicht gerade ein ansi c++ compiller, eher ms c++ ;-).
kann ich die nur zustimmen. es gibt einige sachen die beachtet werden müssen,
wenn man c++ code von der mit gnu programmiert, kompiliert, gelinkt und für
gut befunden wurde
, auf vc6 kompilieren, linken und später ausführen will
( das sizeof() und for(){} problem z.b. ).

viel spass noch beim c++ lernen
d
-oli

links
:
http://www.freshsources.com/newcpp.html
http://www.cplusplus.com/doc/ansi/hfiles.html




Konstruktive Kritik zeichnet sich dadurch aus, dass sie höflich, nützlich und sachlich ist.
bei Antwort benachrichtigen
Yves3 d-oli „ die speak methoden der abgeleiteten klassen sind jetzt auch virtual . heisst...“
Optionen

ich hab jetzt meinen code entsprechend angepasst. bisher stürzte das programm direkt nach der dritten eingabe ab. jetz läuft es bis zum ersten "Wuf!". die warnung zeigt auf diese zeile...
"pRealCat = dynamic_cast ( Zoo[ i ] );"
...und dort passiert jetz anscheinend auch der fehler.

die warnung:
"warning C4541: 'dynamic_cast' fuer polymorphen Typ 'class Mammal' mit /GR- verwendet; unvorhersehbares Verhalten moeglich"

weisst du, was mit "/GR-" gemint ist?

danke für deine ausführlichen antworten!

bei Antwort benachrichtigen
d-oli Yves3 „ich hab jetzt meinen code entsprechend angepasst. bisher stürzte das programm...“
Optionen

gefunden mit google suche: "warning C4541: 'dynamic_cast' fuer polymorphen Typ"

unter: http://mail.ooc.nf.ca/pipermail/ob-users/2001-September/019605.html

>Now I get about 250 compiler warnings (e.g. this one:
>c:\programme\ooc\include\ob\except.h(300) : warning C4541:
>'dynamic_cast' fuer polymorphen Typ 'class CORBA::Exception' mit /GR-
>verwendet; unvorhersehbares Verhalten moeglich)

You *have to* compile with Exception handling activated and RTTI information /GR.

Also ist es vermutlich blos eine Kompiler-Option die du bei den Projekteinstellungen vornehmen must. Ich kenne die Menüführung von VC6 nicht auswendig aber unter optionen und/oder projekteinstellungen ( oder so ähnlich) gibt es irgendwo ein Fenster mit nem Haufen Tabs. Dort kannst du solche einstellungen vornehmen.

Gruss d-oli

Konstruktive Kritik zeichnet sich dadurch aus, dass sie höflich, nützlich und sachlich ist.
bei Antwort benachrichtigen
Yves3 d-oli „gefunden mit google suche: warning C4541: dynamic_cast fuer polymorphen Typ...“
Optionen

ich hab gestern noch den ganzen abend herumgeübt. leider ohne erfolg.
heute versuchte ich es mit linux zu kompillieren.
es hat funktioniert :-).

noch mal danke für deine antworten!

bei Antwort benachrichtigen