gpt4 book ai didi

C++队列模板

转载 作者:太空宇宙 更新时间:2023-11-03 10:36:26 25 4
gpt4 key购买 nike

好的,请原谅我乱七八糟的代码。下面是我的队列类。

#include <iostream>
using namespace std;
#ifndef QUEUE
#define QUEUE

/*----------------------------------------------------------------------------
Student Class

# Methods #
Student() // default constructor
Student(string, int) // constructor
display() // out puts a student

# Data Members #
Name // string name
Id // int id
----------------------------------------------------------------------------*/
class Student {
public:
Student() { }
Student(string iname, int iid) {
name = iname;
id = iid;
}
void display(ostream &out) const {
out << "Student Name: " << name << "\tStudent Id: " << id
<< "\tAddress: " << this << endl;
}

private:
string name;
int id;
};


// define a typedef of a pointer to a student.
typedef Student * StudentPointer;

template <typename T>

class Queue
{
public:
/*------------------------------------------------------------------------
Queue Default Constructor

Preconditions: none
Postconditions: assigns default values for front and back to 0

description: constructs a default empty Queue.
------------------------------------------------------------------------*/
Queue() : myFront(0), myBack(0) {}


/*------------------------------------------------------------------------
Copy Constructor

Preconditions: requres a reference to a value for which you are copying
Postconditions: assigns a copy to the parent Queue.

description: Copys a queue and assigns it to the parent Queue.
------------------------------------------------------------------------*/
Queue(const T & q) {
myFront = myBack = 0;
if(!q.empty()) {
// copy the first node
myFront = myBack = new Node(q.front());
NodePointer qPtr = q.myFront->next;
while(qPtr != NULL) {
myBack->next = new Node(qPtr->data);
myBack = myBack->next;
qPtr = qPtr->next;
}
}

}
/*------------------------------------------------------------------------
Destructor

Preconditions: none
Postconditions: deallocates the dynamic memory for the Queue

description: deletes the memory stored for a Queue.
------------------------------------------------------------------------*/
~Queue() {
NodePointer prev = myFront, ptr;
while(prev != NULL) {
ptr = prev->next;
delete prev;
prev = ptr;
}
}
/*------------------------------------------------------------------------
Empty()

Preconditions: none
Postconditions: returns a boolean value.

description: returns true/false based on if the queue is empty or full.
------------------------------------------------------------------------*/
bool empty() const {
return (myFront == NULL);
}
/*------------------------------------------------------------------------
Enqueue

Preconditions: requires a constant reference
Postconditions: allocates memory and appends a value at the end of a queue

description:
------------------------------------------------------------------------*/
void enqueue(const T & value) {
NodePointer newNodePtr = new Node(value);
if(empty()) {
myFront = myBack = newNodePtr;
newNodePtr->next = NULL;
} else {
myBack->next = newNodePtr;
myBack = newNodePtr;
newNodePtr->next = NULL;
}
}
/*------------------------------------------------------------------------
Display

Preconditions: requires a reference of type ostream
Postconditions: returns the ostream value (for chaining)

description: outputs the contents of a queue.
------------------------------------------------------------------------*/
void display(ostream & out) const {
NodePointer ptr;
ptr = myFront;

while(ptr != NULL) {
out << ptr->data << " ";
ptr = ptr->next;
}
out << endl;
}
/*------------------------------------------------------------------------
Front

Preconditions: none
Postconditions: returns a value of type T

description: returns the first value in the parent Queue.
------------------------------------------------------------------------*/
T front() const {
if ( !empty() )
return (myFront->data);
else
{
cerr << "*** Queue is empty -- returning garbage value ***\n";
T * temp = new(T);
T garbage = * temp;
delete temp;
return garbage;
}
}
/*------------------------------------------------------------------------
Dequeue

Preconditions: none
Postconditions: removes the first value in a queue
------------------------------------------------------------------------*/
void dequeue() {
if ( !empty() ) {
NodePointer ptr = myFront;
myFront = myFront->next;
delete ptr;
if(myFront == NULL)
myBack = NULL;

} else {
cerr << "*** Queue is empty -- "
"can't remove a value ***\n";
exit(1);
}
}
/*------------------------------------------------------------------------
pverloaded = operator

Preconditions: requires a constant reference
Postconditions: returns a const type T

description: this allows assigning of queues to queues
------------------------------------------------------------------------*/
Queue<T> & operator=(const T &q) {
// make sure we arent reassigning ourself
// e.g. thisQueue = thisQueue.
if(this != &q) {
this->~Queue();
if(q.empty()) {
myFront = myBack = NULL;
} else {
myFront = myBack = new Node(q.front());
NodePointer qPtr = q.myFront->next;
while(qPtr != NULL) {
myBack->next = new Node(qPtr->data);
myBack = myBack->next;
qPtr = qPtr->next;
}
}
}
return *this;
}

private:
class Node {
public:
T data;
Node * next;
Node(T value, Node * first = 0) : data(value),
next(first) {}

};
typedef Node * NodePointer;

NodePointer myFront,
myBack,
queueSize;


};

/*------------------------------------------------------------------------
join

Preconditions: requires 2 queue values
Postconditions: appends queue2 to the end of queue1

description: this function joins 2 queues into 1.
------------------------------------------------------------------------*/

template <typename T>
Queue<T> join(Queue<T> q1, Queue<T> q2) {
Queue<T> q1Copy(q1), q2Copy(q2);
Queue<T> jQueue;


while(!q1Copy.empty()) {
jQueue.enqueue(q1Copy.front());
q1Copy.dequeue();
}

while(!q2Copy.empty()) {
jQueue.enqueue(q2Copy.front());
q2Copy.dequeue();
}
cout << jQueue << endl;
return jQueue;

}
/*----------------------------------------------------------------------------
Overloaded << operator

Preconditions: requires a constant reference and a Queue of type T
Postconditions: returns the ostream (for chaining)

description: this function is overloaded for outputing a queue with <<
----------------------------------------------------------------------------*/
template <typename T>
ostream & operator<<(ostream &out, Queue<T> &s) {
s.display(out);
return out;
}

/*----------------------------------------------------------------------------
Overloaded << operator

Preconditions: requires a constant reference and a reference of type Student
Postconditions: none

description: this function is overloaded for outputing an object of type
Student.
----------------------------------------------------------------------------*/
ostream & operator<<(ostream &out, Student &s) {
s.display(out);
}

/*----------------------------------------------------------------------------
Overloaded << operator

Preconditions: requires a constant reference and a reference of a pointer to
a Student object.
Postconditions: none

description: this function is overloaded for outputing pointers to Students
----------------------------------------------------------------------------*/
ostream & operator<<(ostream &out, StudentPointer &s) {
s->display(out);
}
#endif

现在我遇到了一些问题。其一,当我将 0 添加到队列中然后像这样输出队列时......

Queue<double> qdub; 
qdub.enqueue(0);
cout << qdub << endl;

这行得通,它会输出 0。但是例如,如果我以任何方式修改该队列……比如……将它分配给不同的队列……

Queue<double> qdub1; 
Queue<double> qdub2;
qdub1.enqueue(0;
qdub2 = qdub1;
cout << qdub2 << endl;

它会给我奇怪的 0 值,比如 7.86914e-316。

在此方面的帮助将不胜感激!

最佳答案

您尚未定义复制构造函数或赋值运算符。您拥有的那些采用排队类型的实例,而不是另一个队列。对于自己分配和复制队列,编译器仍会使用自动生成的队列,但它们会做错事。

(这可能无法解释该特定片段的输出。)

另一件事是完全错误的(即使再一次,该代码段从不调用此函数,否则您会在整个地方遇到编译器错误):

Queue<T> & operator=(const T &q) {
// make sure we arent reassigning ourself
// e.g. thisQueue = thisQueue.
if(this != &q) {
this->~Queue();

不允许像那样显式调用析构函数,然后继续使用该实例。显式析构函数调用仅与构造具有 new 放置的对象齐头并进。

operator= 通常根据复制构造函数和交换方法(交换两个实例之间的内部表示)来实现:

void swap(Queue<T>& rhv)
{
std::swap(myFront, rhv.myFront);
std::swap(myBack, rhv.myBack);
std::swap(queueSize, rhv.queueSize);
}

Queue<T>& operator=(const Queue<T>& rhv)
{
Queue<T> copy(rhv);
this->swap(copy);
} //the destructor of copy releases the previous contents of *this

关于C++队列模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2678931/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com