[英]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.