C++ Queue类addproduct方法如何访问List类head指针
问题根因
你无法在Queue类中访问List的head成员,是两个代码错误导致的:
- 友元声明位置完全错误:编写List类时你在
insert函数结束后多写了一个},把friend class Queue;挤到了List类的作用域外面,这个友元声明根本不生效,Queue没有访问List私有成员的权限。 addproduct函数本身逻辑和语法有问题:- 函数参数
void addproduct (int choice{缺少右括号,语法无法通过编译 - 函数内直接写
Node *n = head;,head既不是Queue的成员变量,你也没有传入任何List类的实例对象,就算友元生效也无法凭空访问某个链表的head指针。 - 遍历链表时没有做空指针判断,如果传入的choice对应商品不存在,指针走到链表尾部NULL后继续访问成员会直接触发程序崩溃。
- 函数参数
修复方案
- 调整List类的花括号位置,把
friend class Queue;移动到List类的作用域内部,确保友元声明生效。 - 修改
addproduct的函数签名,传入你要读取商品的List实例引用,通过这个实例访问List的私有head指针。 - 补全所有链表遍历逻辑的空指针校验,处理商品不存在的异常场景。
- 入队节点时记得把节点的
next指针置空,避免把原链表中该节点后面的所有商品都意外挂到队列结构上。
修正后的核心代码
class Node{ int data; string food_name; int price; int quantity; public: Node* next; Node(int d,string f_name, int p, int q){ this->data = d; this->food_name = f_name; this->price = p; this->quantity = q; this->next = NULL; } friend class List; friend class Queue; }; class List{ Node * head; Node * tail; public: List():head(NULL),tail(NULL){} Node* begin(){ return head; } void push_front(int data, string food_name, float price, int quantity){ if(head==NULL){ Node*n= new Node(data,food_name, price, quantity); head = tail = n; } else{ Node*n = new Node(data,food_name, price, quantity); n->next = head; head = n; } } void push_back(int data, string food_name, float price, int quantity){ if(head==NULL){ Node*n= new Node(data,food_name, price, quantity); head = tail = n; } else{ Node*n = new Node(data,food_name, price, quantity); tail->next = n; tail = n; } } void insert(int data, string food_name, float price, int quantity, int pos){ if(pos==0){ push_front(data,food_name, price, quantity); return; } Node* temp = head; for(int jump=1; jump<=pos-1;jump++){ temp = temp->next; } Node *n = new Node(data,food_name, price, quantity); n->next = temp->next; temp->next = n; } // 友元声明放在类内部才生效 friend class Queue; }; // List类在此处结束,删除之前错误位置的多余花括号 class Queue{ public: Node * front; Node * rear; Queue(){ front = NULL; rear = NULL; } bool isEmpty(){ return front==NULL && rear==NULL; } bool checkProductExist(int choice){ Node *temp = front; while(temp!=NULL){ if(temp->data == choice){ return true; } temp=temp->next; } return false; } // 补全参数括号,传入要读取的商品列表实例 void addproduct (int choice, List& productList){ // 通过传入的List实例访问其私有head指针 Node *n = productList.head; // 增加空指针判断,避免遍历越界 while(n != nullptr && n->data != choice){ n=n->next; } // 处理商品不存在的场景 if(n == nullptr){ cout<<"选择的商品不存在,添加失败"<<endl; return; } if(isEmpty()){ front = n; rear = n; rear->next = nullptr; cout<<"Node Enqueue successfully"<<endl; } else{ if(checkProductExist(choice)){ Node * temp = front; while(temp!=nullptr && temp->data!=choice){ temp=temp->next; } if(temp != nullptr){ temp->quantity+=1; cout<<"Quantity +1"<<endl; } } else{ rear->next = n; rear = n; rear->next=nullptr; cout<<"Node Enqueue successfully"<<endl; } } } friend class List; };
额外提示
当前实现是直接把List中的节点指针浅拷贝到Queue中,修改Queue内节点的quantity值时,原List中对应商品的数量也会同步被修改。如果不需要这个联动效果,入队时需要新建Node节点,拷贝对应商品的数据做深拷贝。
内容的提问来源于stack exchange,提问作者code cinn
相关产品推荐
相关产品推荐

