I have the following code:
class A
{
};
class B : public A
{
public:
virtual void f() {}
};
int main()
{
A* a = new A();
B* b = static_cast<B*>(a);
b->f();
}
This program fails with a segmentation fault. There are two solutions to make this program work:
- declare f non-virtual
- do not call b->f() (i.e. it fails not because of the cast)
However, both are not an option. I assume that this does not work because of a lookup in the vtable.
(In the real program, A does also have virtual functions. Also, the virtual function is not called in the constructor.)
Is there a way to make this开发者_JS百科 program work?
You can't do that because the object you create is A, not B. Your cast is invalid-- an object of A (created with new) cannot magically become an object of B.
Did you mean the A* a = new A() to actually be A* a = new B()? In that case, I would expect it to work.
You can't do that.
In your example, a is a object of class A. Not B. Casting it to B does not make it a B.
If you want to use polymorphic object behaviors, then you can give virtual function f to class A, and you can use code like A* a = new B();
Then you can use the virtual functions through the a pointer to get behavior from class B.
In your code:
A* a = new A();
You instantiate an A
object. Then you try to use static_cast
to go from a base type to a derived type:
B* b = static_cast<B*>(a);
If the value in a
pointed to an object that actually was of type B
, this would be legal and well-formed. But a
does not point to an object of type B
, it points to an A
, so the cast evokes undefined behavior.
The fix is to change how you instantiate the object. Change:
A* a = new A();
...to:
A* a = new B();
In order to do a static_cast
, you should be sure that the object can be casted, i.e. is an object of class B
.
In this case, I'm sure it isn't.
精彩评论