在派生类上调用虚函数时出现分段错误

时间:2016-12-09 07:29:43

标签: c++

我为这段简短的代码收到了细分错误,而且我无法找出原因。

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);
}

这条线似乎有错误

*ptr=Y_based(3);

当我将其更改为

ptr=&Y_based(3);

我收到了这个编译错误:

taking address of temporary [-fpermissive]

提前致谢。

1 个答案:

答案 0 :(得分:1)

你是对的,行

*ptr=Y_based(3);

不正确。我想,你的意思是ptr指针指向此操作后Y_based类型的新对象。

Hovewer,这条线的意思不同。

首先,计算右侧部分(Y_based(3))。它是Y_based类型的对象,_y字段等于3。之后,计算左侧部分(*ptr)。它是由ptr指针指向的对象,由于指针未初始化,因此未定义。如果指针已初始化,则在此之后,右侧部分的值将分配给左侧部分的值。也就是说,ptr指向的对象会改变,而不是指针本身。

您的理想行为可以通过编写

来实现
ptr = new Y_based(3);

这里分配给左边的部分,它不是ptr指向的对象,而是ptr本身,而右边的部分是指向新创建的{{1}对象的指针}}

此外,由于Y_based类型的对象是由Y_based关键字创建的,因此在您离开块后它不会被销毁,您应该使用{{1}手动处理它在你不再需要该对象的一行。要通过指向基类的指针正确销毁对象,还应该在基类中定义虚拟析构函数:

new

如果您不想打扰所有这些内容,但仍需要具有多态行为,则可以使用引用而不是指针:

delete