简体   繁体   English

在派生类上调用虚拟函数时遇到分段错误

[英]Getting segmentation fault when calling a virtual function on a derived class

I'm getting segmentation fault for this short code and I'm not able to figure out why. 对于此短代码,我遇到了细分错误,但无法弄清原因。

class XorY {
public:
    virtual void set_cost(double& cost){}

};
class X_based:public XorY {
public:
    X_based(int _x):x(_x){}
    void set_cost(double& cost)
    {
        cost=cost*(100-x)/100;
    }
    int x;
};
class Y_based:public XorY
{       
    public:
        Y_based(){}
        Y_based(int _y): y(_y){}
        void set_cost(double& cost){
            cost=cost-y;
        }
        int y;
};


int main(){
    double a=2;
    XorY* type;
    Y_based* ptr;
    *ptr=Y_based(3);
    type=ptr;
    type->set_cost(a);
}

It seems that there's an error with this line 似乎这条线有错误

*ptr=Y_based(3);

When I change it to 当我将其更改为

ptr=&Y_based(3);

I get this compile error: 我收到此编译错误:

taking address of temporary [-fpermissive]

Thanks in advance. 提前致谢。

You're right, the line 你是对的,线

*ptr=Y_based(3);

is incorrect. 是不正确的。 I suppose, you meant that the ptr pointer should point to the new object of type Y_based after this operation. 我想,您的意思是,执行此操作后, ptr指针应指向基于Y_based类型的新对象。

Hovewer, the meaning of this line is different. Hovewer,这条线的意思是不同的。

First, the right part ( Y_based(3) ) is calculated. 首先,计算右侧部分( Y_based(3) )。 It's an object of type Y_based with _y field equal to 3 . 这是类型为Y_based的对象, _y字段等于3 After that, the left part ( *ptr ) is calculated. 之后,计算左部分( *ptr )。 It's the object which is pointed by ptr pointer and it's undefined since the pointer was not initialized. 它是ptr指针指向的对象,并且由于未初始化指针而未定义。 If the pointer was initialized, after that the value of the right part would be assigned to the value of the left part. 如果指针已初始化,则此后,右侧部分的值将分配给左侧部分的值。 That is, the object pointed by ptr would change, not the pointer itself. 也就是说, ptr指向的对象将更改,而不是指针本身。

Your desirable behavior can be achieved by writing 您的期望行为可以通过写作来实现

ptr = new Y_based(3);

Here the left part, which is assigned to, it not the object pointed by ptr , but ptr itself, and the right part is a pointer to a newly created object of type Y_based . 在这里,分配给它的左部分不是ptr指向的对象,而是ptr本身,而右部分是指向新创建的Y_based类型对象的Y_based

Also, since the object of type Y_based was created by the new keyword, it will not be destroyed after you leave the block, and you should take care of it manually, using delete at a line where you don't need the object anymore. 同样,由于类型Y_based的对象是由new关键字创建的,因此在离开该块之后它不会被销毁,因此您应该手动对其进行处理,在不再需要该对象的行上使用delete To correctly destroy an object by the pointer to the base class, you should also define a virtual destructor in the base class: 要通过指向基类的指针正确销毁对象,还应该在基类中定义一个虚拟析构函数:

class XorY {
public:
    virtual void set_cost(double& cost){}
    virtual ~XorY() = default;
};

If you don't want to bother with all this stuff, but still need to have a polymorphic behavior, you can use a reference instead of a pointer: 如果您不想打扰所有这些事情,但是仍然需要具有多态行为,则可以使用引用而不是指针:

int main(){
    double a=2;
    Y_based& ptr = Y_based(3);
    XorY& type = ptr;
    type.set_cost(a);
}

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

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