Here are 2 codes first:
#include<iostream>
using namespace std;
class A{
public:
virtual void f()
{
cout<<"A"<<endl;
}
};
class B: public A{
public:
virtual void f()
{
cout<<"B"<<endl;
}
};
int main()
{
A* pa=new A();
B* pb=new B();
A* upCastpa= static_cast<A*>(pb);
B* downCastpb=static_cast<B*>(pa);
upCastpa->f();
downCastpb->f();
return 1;
}
one display
B
A
Therefore I think what really matters is the objected the pointer pointing to. However, if I remove virtual form A::f(), like this;
#include<iostream>
using namespace std;
class A{
public:
void f()
{
cout<<"A"<<endl;
}
};
class B: public A{
public:
virtual void f()
{
cout<<"B"<<endl;
}
};
int main()
{
A* pa=new A();
B* pb=new B();
A* upCastpa= static_cast<A*>(pb);
B* downCastpb=static_cast<B*>(pa);
upCastpa->f();
downCastpb->f();
return 1;
}
The code will displayed A "stop" What happened? If the important thing is the objected the pointer pointing to.
it suppose to display A B instead of corrupted.
what happened?
I really appreciate any advice or instruction. Thanks a lot.
Irrespective of the presence or absence of virtual
function:
A* pa=new A();
B* downCastpb=static_cast<B*>(pa);
causes an Undefined Behavior.
When you use static_cast
to cast an object to a type that it is not, it causes Undefined behavior. Once you have an code that produces undefined behavior it is useless to try and find reasoning for the output observed. The compiler is free to show any behavior, a crash, a weird result or an absoultely fine working code.You are completely at the mercy of the compiler.
Reference:
C++11 Standard 5.2.9 [expr.static.cast]
A prvalue of type "pointer to cv1
B
", whereB
is a class type, can be converted to a prvalue of type "pointer to cv2D
", whereD
is a class derived fromB
, if a valid standard conversion from "pointer toD
" to "pointer toB
" exists, cv2 is the same cv-qualification as, or greater cv-qualification than, cv1, andB
is neither a virtual base class ofD
nor a base class of a virtual base class ofD
. The null pointer value is converted to the null pointer value of the destination type. If the prvalue of type "pointer to cv1B
" points to aB
that is actually a subobject of an object of typeD
, the resulting pointer points to the enclosing object of typeD
. Otherwise, the result of the cast is undefined.