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

标签 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]

提前致谢。

最佳答案

你是对的,线

*ptr=Y_based(3);

不正确。我想,你的意思是 ptr 指针应该在这个操作之后指向 Y_based 类型的新对象。

然而,这一行的意思是不同的。

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

你想要的行为可以通过写作来实现

ptr = new Y_based(3);

这里左边部分,赋值给的不是ptr指向的对象,而是ptr本身,右边部分是指向新创建的对象的指针Y_based 类型的对象。

另外,由于Y_based类型的对象是由new关键字创建的,离开 block 后它不会被销毁,你应该好好照顾它手动,在不再需要该对象的行中使用 delete。要通过指向基类的指针正确销毁一个对象,您还应该在基类中定义一个虚拟析构函数:

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

如果您不想为所有这些事情操心,但仍然需要多态行为,您可以使用引用而不是指针:

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

关于c++ - 在派生类上调用虚函数时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41055228/

相关文章:

c++ - CreateInstance 返回 "The specified module could not be found."

c++ - std线程调用模板类: compiler error的模板成员函数

javascript - 带有自己的 headless 浏览器的 Heisenbug

c++ - 这段代码中发生了什么?重新解释_cast<int*>(buf)

c++ - "local variables at the outermost scope of the function may not use the same name as any parameter"是什么意思?

c++ - 我怎样才能部分特化枚举值的类模板?

C++ 将元素复制到新列表中

c++ - 设置 vtkLegendScaleActor 对象的位置

c++ - 在关闭异常处理的应用程序中使用启用异常处理的库

c++ - 在 C++ 中写入现有的空格二进制文件