简体   繁体   English

在C ++中进行强制转换操作后,在子级中使用虚函数

[英]Using virtual function in child after casting operation in C++

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: 有两种解决方案可以使该程序正常工作:

  1. declare f non-virtual 声明为非虚拟
  2. do not call b->f() (ie it fails not because of the cast) 不要调用b-> f()(即它不是由于强制转换而失败)

However, both are not an option. 但是,两者都不是选择。 I assume that this does not work because of a lookup in the vtable. 我假设由于在vtable中进行查找而导致此操作不起作用。

(In the real program, A does also have virtual functions. Also, the virtual function is not called in the constructor.) (在实际程序中,A确实也具有虚函数。此外,在构造函数中未调用该虚函数。)

Is there a way to make this 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. 您不能这样做,因为您创建的对象是A,而不是B。您的转换无效– A的对象(用new创建)不能神奇地成为B的对象。

Did you mean the A* a = new A() to actually be A* a = new B()? 您是说A * a =新A()实际上是A * a =新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. 在您的示例中,a是类A的对象。不是B。将其强制转换为B不会使它成为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(); 如果要使用多态对象行为,则可以将虚函数f赋予类A,并且可以使用A* a = new B();这样A* a = new B();代码A* a = new B(); Then you can use the virtual functions through the a pointer to get behavior from class B. 然后,您可以通过指针使用虚函数从类B获取行为。

In your code: 在您的代码中:

    A* a = new A();

You instantiate an A object. 您实例化一个A对象。 Then you try to use static_cast to go from a base type to a derived type: 然后尝试使用static_cast从基本类型转换为派生类型:

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. 如果值a尖到一个对象,它实际上是类型的B ,这将是合法和良好的。 But a does not point to an object of type B , it points to an A , so the cast evokes undefined behavior. 但是a并不指向B类型的对象,而是指向A ,因此强制转换会引发未定义的行为。

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, ie is an object of class B . 为了进行static_cast ,应确保可以 static_cast该对象,即该对象是B类的对象。

In this case, I'm sure it isn't . 在这种情况下,我确定不是

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM