Re: Not what I expected from some exception code (throw/try/catch)
<stevewilliams2004@comcast.net> wrote in message...
I was wondering if someone could explain the output I am getting for
the program below. What I expected from the main program output was
"Cat" but instead I see "Mammal". The output is also included below.
I got the same results with GCC 3.4.4 under cygwin as with MSDev
studio 2003. Even stranger to me, if I change the catch statement to
catch a Cat instead of a Mammal, the program crashes in the catch
body, during the call to m.MyType(). Thanks for any explanations in
advance.
Program:
#include <iostream>
using namespace std;
class Mammal{ public:
Mammal(){
cout<<"Constructing Mammal @ "<<this<<std::endl;
}
Mammal( Mammal const &source ){
cout<<"Copy Constructing Mammal @ "<<this
<<" from "<<&source<<std::endl;
}
// ~Mammal(){
// [Warning] class Mammal' has virtual functions but
// non-virtual destructor
// [Warning]`class Cat' has virtual functions but
// non-virtual destructor
virtual ~Mammal(){ // this quiets both warnings
cout<<"Destructing Mammal @ "<<this<<std::endl;
}
virtual const char* MyType(){
return "Mammal";
}
};
// no change to Cat
class Cat : public Mammal{ public:
Cat(){
cout<<"Constructing Cat @ "<<this<<std::endl;
}
Cat( Cat const &source ){
cout<<"Copy Constructing Cat @ "<<this
<<" from "<<&source<<std::endl;
}
~Cat(){
cout<<"Destructing Cat @ "<<this<<std::endl;
}
virtual const char* MyType(){
return "Cat";
}
};
int main(int argc, char *argv[]){
Cat fluffy;
Mammal &fluffyRef = fluffy;
try{
throw fluffyRef; // to get 'Mammal' (a sliced 'Cat')
// out: Copy Constructing Mammal @ 0xc5fb80
// from 0xacee04 (Cat fluffy)
// throw fluffy; // to get 'Cat'
// Copy Constructing Cat @ 0xc5fb80 from 0xacee04
}
// add:
catch( Cat const &m ){
cout<<"Caught a "<<m.MyType()<<std::endl;
return EXIT_FAILURE;
}
catch( Mammal &m ){
cout << "Caught a " << m.MyType() << endl;
return 0;
}
// add:
catch( ... ){ // that's 3 dots (not a placeholder)
cout<<"Caught something, maybe the flu!"<<std::endl;
return EXIT_FAILURE;
}
cout << "Nothing Caught" << endl;
return 0;
}
[ I'm not positive, this is my guess. ]
Your 'fluffyRef' is a ref to 'Mammal'. If you only caught 'Cat &c' (and not
'Mammal'), the program will exhibit an "un-caught exception" and terminate
which looks like a crash).
try{
throw fluffy;
}
// catch( Cat &m ){
// cout<<"Caught a "<<m.MyType()<<std::endl;
// }
catch( Mammal &m ){
cout<<"Caught a "<<m.MyType()<<std::endl;
Cat *cat = dynamic_cast<Cat*>( &m );
if( cat ){ cout<<"It's a Cat!!"<<std::endl;}
}
// out: Caught a Cat
// out: It's a Cat!!
throw fluffyRef;
// out: Caught a Mammal
// The cast fails, which I think is slicing the Cat (at throw).
--
Bob R
POVrookie