基于双向链表双端队列的文档节点程序:模板声明问题求助
Hey there! Let's work through your double-linked deque problem—sounds like you're stuck on template declarations in Node.h and getting your Document class set up correctly. Let's break this down step by step.
First, let's address your incomplete Document class. A few issues stand out: your priority should probably be a fixed integer (since you're using 1/2 for insertion rules), and you're missing constructor implementations plus proper access to the class members for your Node/deque.
Here's a corrected version:
template<class T> class Document { private: T name; int pri; // Priority is 1 or 2, so int makes more sense than generic T public: // Constructor with member initializer list Document(T docName, int priority) : name(docName), pri(priority) {} // Getter methods to let Node/deque access private data T getName() const { return name; } int getPriority() const { return pri; } };
Note: If you really need priority to be a generic type, you can swap int back to T—just make sure your insertion logic handles valid priority values properly.
Your Node class needs to be a template that works with the Document template. We'll add forward declarations to avoid circular dependency issues, plus proper pointers for the double-linked structure.
Here's the fixed Node.h:
// Forward declaration of Document to resolve circular dependency template<class T> class Document; template<class T> class Node { private: Document<T> data; Node<T>* prev; Node<T>* next; public: // Constructor that takes a Document object Node(const Document<T>& doc) : data(doc), prev(nullptr), next(nullptr) {} // Getters/setters for pointers and data Node<T>* getPrev() const { return prev; } Node<T>* getNext() const { return next; } void setPrev(Node<T>* p) { prev = p; } void setNext(Node<T>* n) { next = n; } const Document<T>& getData() const { return data; } };
Now let's build the deque itself, with logic to insert at the head (priority 1) or tail (priority 2), plus basic remove and print functionality.
#include <stdexcept> #include <iostream> template<class T> class DoubleLinkedDeque { private: Node<T>* head; Node<T>* tail; int size; public: DoubleLinkedDeque() : head(nullptr), tail(nullptr), size(0) {} // Insert logic based on priority void insert(const Document<T>& doc) { Node<T>* newNode = new Node<T>(doc); if (size == 0) { // Empty deque: new node is both head and tail head = tail = newNode; } else if (doc.getPriority() == 1) { // Insert at head newNode->setNext(head); head->setPrev(newNode); head = newNode; } else if (doc.getPriority() == 2) { // Insert at tail newNode->setPrev(tail); tail->setNext(newNode); tail = newNode; } else { // Invalid priority: clean up and throw error delete newNode; throw std::invalid_argument("Priority must be 1 or 2"); } size++; } // Remove from head bool removeFront() { if (size == 0) return false; Node<T>* temp = head; if (size == 1) { head = tail = nullptr; } else { head = head->getNext(); head->setPrev(nullptr); } delete temp; size--; return true; } // Remove from tail bool removeBack() { if (size == 0) return false; Node<T>* temp = tail; if (size == 1) { head = tail = nullptr; } else { tail = tail->getPrev(); tail->setNext(nullptr); } delete temp; size--; return true; } // Print deque contents for testing void printDeque() const { Node<T>* current = head; while (current != nullptr) { std::cout << "Document: " << current->getData().getName() << ", Priority: " << current->getData().getPriority() << "\n"; current = current->getNext(); } } // Destructor to prevent memory leaks ~DoubleLinkedDeque() { while (removeFront()); } };
Test your deque with this sample main function:
#include <string> #include "Document.h" #include "Node.h" #include "DoubleLinkedDeque.h" int main() { DoubleLinkedDeque<std::string> myDeque; // Insert documents with different priorities myDeque.insert(Document<std::string>("Annual_Report.pdf", 1)); myDeque.insert(Document<std::string>("Vacation_Photo.jpg", 2)); myDeque.insert(Document<std::string>("Meeting_Notes.txt", 1)); std::cout << "Initial Deque:\n"; myDeque.printDeque(); // Remove from front and tail myDeque.removeFront(); std::cout << "\nAfter removing front:\n"; myDeque.printDeque(); myDeque.removeBack(); std::cout << "\nAfter removing back:\n"; myDeque.printDeque(); return 0; }
- Template Syntax: Always start template class definitions with
template<class T>(watch for typos like your incompletetempla...). - Memory Leaks: Always delete nodes when removing them, and use the destructor to clean up the entire deque.
- Access Control: Use getters (or friend declarations) to let Node/deque access Document's private members—don't try to access them directly.
- Edge Cases: Handle empty deques and deques with only one node to avoid null pointer crashes.
内容的提问来源于stack exchange,提问作者Arnau Martíñez

