Reputation: 1180
Might answered some where else, but could not found right phrase to ask
so hear it goes.
I have base class A
, with child B
and C
; (completely for training purpose)
#include <iostream>
class A
{
public:
virtual void print () { std::cout<< "A::print()" << std::endl; }
};
class B: public A
{
public:
void print () { std::cout<< "B::print()" << std::endl; }
};
class C : public B
{
public:
void print () { std::cout<< "C::print()" << std::endl; }
};
so, in my main I have declared base pointer A*
bptr; later child's B
and C
also declared.
later bPtr pointed to B
and called print
function works as expected;
later bPtr pointed to C
and called print
function works as expected;
hear is code, no problems hear.
int main()
{
A* bPtr;
B b;
C c;
bPtr = &b;
bPtr->print(); // prints B::print() - as expected;
bPtr = &c;
bPtr->print(); // prints C::print() - as expected;
}
hear is my dilemma, I may understand wrong;
now what I thought all these days, dynamic_cast
also does exactly above;
but things are different OR I am doing something wrong.
int main()
{
A* bPtr = new C;
bPtr = dynamic_cast<B*>( bPtr );
bPtr->print(); // prints C::print() - expected B::print()
/*
I know above can be correct with explicit call
*/
(dynamic_cast<B*>( bPtr ))->B::print(); // B::print
bPtr = dynamic_cast<C*>( bPtr );
bPtr->print(); // prints C::print()
return 0;
if ( B* b = dynamic_cast<B*>( bPtr ))
{
b->print(); // still calls C::print() anyway;
}
}
so hear is my question is dynamic_cast
good for and only places like if
statement to determine
the existence of inheritance between base and child's or safe cast between base and child's?
if ( B* b = dynamic_cast<B*>( bPtr ))
{
b->print(); // still calls C::print() anyway;
}
Upvotes: 0
Views: 125
Reputation: 3248
This behaviour has nothing to do with dynamic_cast.
The behaviour of a virtual call will always depend on the actual runtime type of the value. In your second example, the only thing actually constructed is a C
, so all calls will resolve to C, whether you call it an A: A * a = bPtr
or a B: B * b = bPtr
, it will resolve to C::print() because the statement new C
constructs the actual value as a C.
Dynamic_cast is just going to cast the value given to the type specific, if it is (a subtype of) that type, or otherwise return nullptr
. So dynamically casting a B *
to C *
will fail and return nullptr
, but in your case you are casting C *
to one of its base types, which will always succeed and never change the value itself.
Upvotes: 2