(e-mail address removed) wrote in message ...
This is down-casting and the pointer of object of child class Derived3
is pointing to object of parent class Base3.
The Base3 reference (a) is 'holding' an object of Derived3, or object of type
Base3, or object of type derived from Base3, etc.. Read on....
I don't read a warning
message from g++ for this line, but get a message for a similar line of
my code at line 16, why?
$ make
g++ -std=c++98 -pedantic a.cpp -c -o a.o
a.cpp: In function `int main()':
a.cpp:16: warning: dynamic_cast of `Base3 b' to `class Derived3*'
can never succeed
g++ -std=c++98 -pedantic a.o -o a.out
$
My docs don't show a 'c++98' option for '-std='( which is for 'C', and
supposed to be ignored for 'C++'). Try removing the '-std=c++98' (unless your
docs say it is supported).
(of course you will still get the *warning* because you are casting a base to
a derived, and the compiler has determined that in this situation (line 16)
it can never succeed. In my little 'TellMe()', it's not sure, so doesn't
warn. Pretty smart compiler, eh?).
I compiled on MinGW(GCC3.3.1). What version are you using?
I can't imagine a newer standard would forbid downcasting, it would break
much code.
A failed downcast (line 16) should just produce a zero (or NULL if you
prefer).
<loose wording>
Why does the compiler 'warn'? One reason could be the possibility to 'slice'
the object. In my example, there is nothing there. But, what if I added
things to the derived class. Those added things could be removed (like during
a copy operation) under some conditions. (look up 'pure virtual' and "object
slicing" if you don't know about them.). Most books demonstrate that, and you
should try the examples (if you haven't already.).
A derived class will almost always have things that the base class
doesn't[1]. The compiler warns you, "Hey, you sure you want to do that? You
might try to call a function that isn't there!". A dog is always an animal,
but, an animal is not always a dog. Ever try to pet a rattlesnake? (they
won't chase cars or retrieve a stick either!<G>).
[1] - or different, like defined a pure virtual.
/*a.cpp*/
#include <iostream>
class Base3{public: virtual ~Base3(){}};
class Derived3 : public Base3{};
void TellMe( Base3 &a, std::string &rtn){
rtn = "I'm an type Base3!";
Derived3 *cp = dynamic_cast<Derived3*>( &a );
if(cp) rtn += " It's also an Derived3.";
return;
}
int main(){
Base3 b;
Derived3 d;
Derived3 *p1 = dynamic_cast<Derived3*>(&b); //line 16
if( p1 ){ // check downcast
std::cout<<"dynamic_cast<Derived3*>(&b); GOOD"<<std::endl;
}
else{
std::cout<<"dynamic_cast<Derived3*>(&b); FAILED"<<std::endl;
}
// compile and run it, you should *always* see 'FAILED'.
// that is what the compiler was warning about.
Base3 *p2 = dynamic_cast<Base3*>(&d);
if( p2 ){ // check upcast
std::cout<<"dynamic_cast<Base3*>(&d); GOOD"<<std::endl;
}
else{
std::cout<<"dynamic_cast<Base3*>(&d); FAILED"<<std::endl;
}
// should see 'GOOD'.
Derived3 *p3 = dynamic_cast<Derived3*>( p2 );
if( p3 ){ // cast it back
std::cout<<"dynamic_cast<Derived3*>( p2 ); GOOD"<<std::endl;
}
else{
std::cout<<"dynamic_cast<Derived3*>( p2 ); FAILED"<<std::endl;
}
// should see 'GOOD'.
But, again, my point was - code. If you were reading a book written using an
old compiler, the author may not have been aware of the warning you got by
trying the code.
[ experts - corrections welcomed ]