C++队列类实现template模板报C2227错误,代码问题排查咨询
问题诊断与修复方案
你触发C2227错误的核心原因是SQueue的模板逻辑设计错误:当你实例化SQueue<int>时,模板参数T被推导为int,而你代码中SQueue的front、end成员声明为T*也就是int*,内置类型int没有elem、next成员,调用np->elem自然报错。
所有需要修改的问题点
- SQueue节点类型错误:SQueue存储的元素类型是
T,链表节点应该是SNode<T>而非T本身,需要把SQueue内部所有指针类型从T*改为SNode<T>* - SNode类设计错误:
SNode的elem成员类型写死为int,不符合模板设计要求,需改为T- SNode构造函数初始化列表中给
elem赋值字符串字面量" ",类型不匹配,改为T()默认初始化 - 放开
SQueue<T>的友元声明,否则SQueue无法访问SNode的私有成员
- 主函数typedef冗余且易混淆:
typedef SQueue<int> SQueue;写法没必要,直接实例化模板类即可 - 头文件依赖缺失:SQueue中用到了
cout,需要包含<iostream>头文件 - 额外逻辑漏洞:dequeue操作后如果队列变空,需要将
end指针也置空,避免后续enqueue操作出错
修正后代码
SNode.h
#include <string> using namespace std; template <class T> class SQueue; // 前置声明SQueue类 template <class T> class SNode { private: T elem; // 改为泛型T SNode<T>* next; // 节点指针类型是SNode<T> explicit SNode(); friend class SQueue<T>; // 放开友元声明 }; template <class T> SNode<T>::SNode() : elem(T()), next(nullptr) {} // 默认初始化elem
SQueue.h
#include <iostream> #include <string> #include "SNode.h" using namespace std; template <class T> class SQueue { public: SQueue(); void enqueue(T); void dequeue(); void print(); private: SNode<T>* front; // 改为SNode<T>指针 SNode<T>* end; // 改为SNode<T>指针 }; template <class T> SQueue<T>::SQueue() : front(nullptr), end(nullptr) {} // 用nullptr代替NULL template <class T> void SQueue<T>::enqueue(T e) { SNode<T>* np = new SNode<T>(); // 实例化SNode节点 np->elem = e; np->next = nullptr; if (front == nullptr && end == nullptr) { front = end = np; return; } end->next = np; end = np; } template <class T> void SQueue<T>::dequeue() { SNode<T>* np = front; if (front == nullptr) { cout << "The queue is empty-1!" << endl; return; } front = front->next; // 队列空的时候同步置空end指针 if (front == nullptr) { end = nullptr; } delete np; } template <class T> void SQueue<T>::print() { if (front == nullptr) { cout << "The queue is empty-2!" << endl; return; } for (SNode<T>* temp = front; temp != nullptr; temp = temp->next) { if (temp != front) { cout << " <- "; } cout << temp->elem; } cout << " [Queue: FIFO- First In First Out]" << endl; }
主函数代码
#include <iostream> #include "SQueue.h" using namespace std; int main() { SQueue<int> SQ; // 直接实例化模板类 cout << "Queue 1: "; SQ.enqueue(1); SQ.enqueue(2); SQ.enqueue(3); SQ.enqueue(3); SQ.print(); SQ.dequeue(); SQ.dequeue(); SQ.print(); return 0; }
额外注意
C++模板类的实现和声明不能拆分到不同的cpp文件,要放在同一个头文件里,否则会出现链接错误,你当前将模板实现都放在头文件的写法是符合要求的。
内容的提问来源于stack exchange,提问作者Matt_Ag
相关产品推荐
相关产品推荐

