队列类无法正确出队

3
我昨天在这里提出了一个类似的问题,并纠正了其中的一些问题,但主要问题仍然存在。我将Position对象入队和出队到一个Position队列中。当我入队两个不同的Position对象并将它们都出队时,返回的两个Position对象具有与第二个放入的对象相同的值。当我在enqueue函数内部检查已经入队的值时,它们是正确的。我不明白为什么这样做不起作用,因为我已经解决了逻辑问题,并从一本书中直接使用了出队算法。Position类有三个基于数组的堆栈作为私有成员。
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;
    }
1个回答

1

抱歉,伙计,你的代码有很多问题。其中一些似乎是复制/粘贴错误,但其他则显示出对C++的理解不足。我将首先关注后者。

成员函数void Position::enqueue(Position n)通过值复制所有传递的参数。那么当你调用它时会发生什么?参数被复制,并且在函数内部,你正在处理这个副本,它将在函数作用域结束时被释放。因此,赋值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指令通常应放在源文件的前几行中。

大部分错误都是因为我长时间使用它而产生的,但是非常感谢您的解释,现在它可以正常工作了 :) - user1198783
我很高兴能够帮忙。如果我可以建议,买一本好的C++书籍,效果非常好。 - gwiazdorrr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接