我写了一个c++的循环单链表,在链表类的定义中声明定义了一个节点Node结构体,并使用这个结构作为成员函数返回类型,然后报错说该结构体无法作为type.
//Link.h
#ifndef LINK_H
#define LINK_H
using namespace std;
class Link {
public:
Link(){
head = new Node();
head->next = head;
tail = head;
size = 0;
};
// ~Link(){}
public:
void pushhead(int value);
void pushback(int value);
void insert(int value, int index);
void popback(void);
void pophead(void);
void pop(int index);
void allremove(int value);
Node* find (int index) ;
bool match(int value);
void show(void);
private:
struct Node{
int data;
Node* next;
Node(int d=0):data(d),next(NULL){}
};
Node* head;
Node* tail;
int size;
};// Link
#endif //LINK_H
//Link.cpp
//
// Created by Mr.W on 25-1-4.
//
#include<iostream>
#include "Link.h"
using namespace std;
//void pushhead(int value);
//void pushback(int value);
//void insert(int value, int index);
//void popback(void);
//void pop(int index);
//void allremove(int value);
//bool find(int index);
//bool match(int value);
//void show(void);
void Link::pushhead(int value){
Node *node = new Node(value);
node->next = head->next;
this->head->next = node;
if(node->next == head){
this->tail = node;
}
this->size++;
return;
}
void Link::pushback(int value) {
Node *node = new Node(value);
node->next = tail->next;
this->tail->next = node;
this->tail = node;
this->size++;
return ;
}
void Link::insert(int value, int index) {
if (index == 0) {
this->pushhead(value);
}
else if (index == this->size) {
this->pushback(value);
}
else if (index>0 && index<this->size) {
Node *node = new Node(value);
Node *temp = this->head->next;
for (int i = 0; i < index-1; i++) {
temp = temp->next;
}
node->next = temp->next;
temp->next = node;
this->size++;
}
else {
std::cout<<"index out of range"<<std::endl;
}
return ;
}
void Link::popback(void) {
if (head->next == head) {
return ;
}
Node *temp = head;
while (temp->next != tail) {
temp = temp->next;
}
temp->next = tail->next;
delete tail;
tail = temp;
this->size--;
return;
}
void Link::pophead(void) {
if (head->next == head) {
return ;
}
Node *temp = this->head->next;
this->head->next = temp->next;
delete temp;
this->size--;
return;
}
void Link::pop(int index) {
if (index == 0) {
this->pophead();
}
else if (index>0 && index<this->size) {
Node *temp = this->head->next;
for (int i = 0; i < index-1; i++) {
temp = temp->next;
}
Node *t = temp->next;
temp->next = temp->next->next;
delete t;
this->size--;
if (temp->next == head) {
this->tail = temp;
}
}
else {
std::cout<<"index out of range"<<std::endl;
}
return ;
}
void Link::allremove(int value) {
if (this->size==0) {
return ;
}
Node *p = this->head->next;
Node*q = this->head;
while (p != head) {
if (p->data==value) {
q->next = p->next;
if (p->next == head) {
this->tail = q;
}
delete p;
this->size--;
p = q->next;
}
else {
p = p->next;
q = q->next;
}
}
return ;
}
bool Link::match(int value) {
if (this->size==0) {
return false;
}
Node *p = this->head->next;
while (p != head) {
if (p->data==value) {
return true;
}
p = p->next;
}
return false;
}
Link::Node* Link::find(int index) {
if (this->size==0) {
return false;
}
if (index>=0 && index<this->size) {
Node *p = this->head->next;
for (int i = 0; i < index; i++) {
p = p->next;
}
return p;
}
std::cout<<"index out of range"<<std::endl;
return NULL;
}
void Link::show(void){
Node *p = this->head->next;
if(p==head){
std::cout<<"Link list is empty"<<std::endl;
}
while(p != head){
std::cout<<p->data<<" ";
p = p->next;
}
std::cout<<std::endl;
return ;
}
//main.cpp
#include <iostream>
#include"Link.h"
using namespace std;
int main() {
Link temp;
temp.pushhead(5);
temp.show();
temp.pushback(6);
temp.show();
temp.insert(7,1);
temp.show();
temp.pushback(5);
temp.pushhead(7);
temp.show();
// std::cout<<"Find? "<<temp.match(4)<<std::endl;
std::cout<<temp.find(4)->data<<std::endl;
// temp.allremove(5);
// temp.show();
return 0;
}
询问过文心一言,告诉我这样定义没有问题:类中声明的结构体与成员函数顺序不重要,但是clion就是报错。我尝试过将结构体在类中提前到成员函数之前,或在类声明前定义结构体,两种行为都能正确编译运行。
可以将 Node 结构体的定义移到 Link 类的外部,或者在使用 Node 结构体时加上 Link:: 作用域限定符。
将 Node 结构体的定义移到 Link 类的外部:
或者在使用 Node 结构体时加上 Link:: 作用域限定符:
补充
第一种方法是将 Node 结构体定义在 Link 类的外部,使其成为一个全局结构体。第二种方法是在类成员函数定义时使用 Link::Node 来明确指定 Node 是 Link 类的内部结构体。