ducdohuunguyen Ответов: 1

Простая ошибка класса очереди


У меня есть очень простой класс очереди
Заголовочный файл: Queue. h

#ifndef QUEUE_H
#define QUEUE_H
struct Node
{
	int data;
	Node* link;
};
typedef Node* nodeptr;
class Queue
{
public:
	Queue();
	~Queue();
	void add(int number);
	int remove();//removes the top node of the queue and return its value
	bool empty() const;
protected:
	nodeptr front;
	nodeptr back;
};
#endif //QUEUE_H 


Файл реализации: Queue.cpp

#include "Queue.h"
#include <cstdlib>
#include <iostream>
#include <cstddef>
using namespace std;
Queue::Queue():front(NULL),back(NULL)
{}
Queue::~Queue()
{
	int next;
	nodeptr discard;
	discard=front;
	while (discard!=NULL)
	{
		next=remove();
		discard=front;
	}
}
void Queue::add(int number)
{
	if (empty())
	{
		front=new Node;
		front->data=number;
		front->link=NULL;
		back=front;
	}
	else
	{
		nodeptr temp;
		temp=new Node;
		temp->data=number;
		temp->link=NULL;
		back->link=temp;
		back=temp;
	}
}
int Queue::remove()
{
	if (empty())
	{
		cout<<"error removing from an empty queue\n";
		exit(1);
	}
	else
	{
		int result=front->data;
		nodeptr discard;
		discard=front;
		front=front->link;
		if (front==NULL)
		{
			back=NULL;
		}
		delete discard;
		return result;
	}
}
bool Queue::empty() const
{
	return (front==NULL);
}


У меня есть две версии основной программы, которые в основном одинаковы, но дают разные результаты, несмотря на то, что класс остается нетронутым.
Основная версия 1-выход: 4321

#include "Queue.h"
#include<iostream>
using namespace std;

int main()
{
	Queue a;
	a.add(1);
	a.add(2);
	a.add(3);
	a.add(4);
	cout<<a.remove()<<a.remove()<<a.remove()<<a.remove();
}


Основная версия 2-выход:
1
2
3
4

#include "Queue.h"
#include<iostream>
using namespace std;
int main()
{
	Queue a;
	a.add(1);
	a.add(2);
	a.add(3);
	a.add(4);
	cout<<a.remove()<<endl;
	cout<<a.remove()<<endl;
	cout<<a.remove()<<endl;
	cout<<a.remove()<<endl;
}



Что я уже пробовал:

У меня есть изменения между обеими версиями сотни раз, но результаты остаются неизменными. Что я здесь сделал не так?

1 Ответов

Рейтинг:
9

Patrice T

Компилятор языка Си - это рерайтер. Это означает, что компилятор решает порядок вычисления частей в одной строке исходного кода.

cout<<a.remove()<<a.remove()<<a.remove()<<a.remove();
Компилятор считает, что более эффективно вычислять в обратном порядке;
Вы можете проверить это:
cout<<a.remove()+10<<a.remove()+20<<a.remove()+30<<a.remove()+40;


ducdohuunguyen

Знаете ли вы какой-нибудь способ предотвратить такое поведение?

Patrice T

Использовать ваш вариант 2