我昨天在这里问了一个类似的问题,我纠正了一些问题,但主要问题仍然存在
我正在将Position对象排队和出队到Position队列中。当我将两个不同的Position对象排入队列,并将它们都退出队列时,返回的两个Position对象的值与放入的第二个对象的值相同。当我检查入队函数中已入队的值时,它们是正确的。我不明白这是怎么回事,因为我逐字逐句地计算出了逻辑并使用了出列算法;
Position类有3个基于数组的堆栈作为私有成员
struct Posnode
{
Position *pos;
Posnode *next;
};
class Position
{
private:
Posnode *front,*back,header; //front = back = &header;
Pegs A,B,C;
Position::Position(int num): A(num), B(num), C(num)
{
front = back = &header;
A.assignpeg(num);//assigning 1 to n to each Peg
B.assignpeg(num);
C.assignpeg(num);
}
#include "Pegs.h"
#include "Position.h"
int main ()
{
Position pos(4), intial(3),p,m,n;
intial.geta();//poping Peg A stack
pos.getc();//poping Peg c stack
p.enqueue(intial);
p.enqueue(pos);
p.dequeue(m);//position 'pos' is returned rather than intial
p.dequeue(n);//position 'pos' is returned
cin.get();
return 0;
}
void Position::dequeue(Position&)
{
Position p;
Posnode *ptr=front->next;//front points to an empty node wi
p = *ptr->pos;//assigning the position in ptr to p
front->next = ptr->next;
if (back == ptr) {//if im at the end of the queue
back = front;
}
delete ptr;
return ;
}
void Position::enqueue(Position n)
{
Posnode *ptr = new Posnode;
ptr-> pos = &n;//copying Position n calls Pegs operator =
back->next = ptr;//values that are enqueued check back ok
back = ptr;
return;
}
Pegs& Pegs::operator=(const Pegs & ori)//Pegs copy contructor
{
top=-1;
disks = ori.disks;
peg = new int[disks];
int element=0,g=-1,count=0;
while (count <= ori.top)//copying elements if there are any in ori
{
++count;
element=ori.peg[++g];
push(element);
}
return *this;
}
成员函数void Position::enqueue(Position n)
按值复制所有传递的参数。那么,当你这样称呼它时会发生什么呢?参数会被复制,并且在您正在处理的函数内部此复制将在函数的作用域结束时被处理。因此,assignenemtn ptr-> pos = &n
将向pos
分配临时对象的地址。只要没有任何内容写入,已处理对象地址处的数据可能在一段时间内仍然有效,但您应该永远不要依赖于这种行为。您应该做的是通过引用传递参数,即将声明更改为void Position::enqueue(Position& n)
。这样,实际对象将被传递,而不是自动复制。
如果你没有像在void Position::dequeue(Position&)
中那样为参数指定名称,你将无法访问它。在这个函数中,你可以创建一个局部变量p
,然后将结果分配给它。但因为p
是局部的,所以当函数返回时,它将被释放。不用说,传递给函数的参数是不可访问的,因为它是未命名的。您应该做的是这样声明函数:void Position::dequeue(Position& p)
。
作为一个很好的建议:你应该更好地隔离你的病例。例如,Pegs
与您遇到的问题有任何联系吗?还要避免像Posnode *front,*back,header
这样的声明——在大多数情况下,它们会使代码更难阅读。您注意到您的代码在类主体中有#include
吗?!你永远不应该这样做,除非你知道自己在做什么。#include
指令通常应该放在源文件的第一行。