模板朋友类和的C++错误
C++ errors with template friend classes and
我正在创建自己的双链表程序(我知道有一个列表库(。我有我的main.cc,只有我的主函数,它提供了一个菜单,可以为我的程序选择各种选项,并调用正确的函数/对象。然后,我有3个不同的头文件,其中包含类文件,1个是我的双链表函数的通用文件,另一个是将通用DLL函数转换为队列函数,最后一个是转换为堆栈函数。
main.cc
#include <iostream>
#include "doubly-linked-list.h"
#include "DLLstack.h"
#include "DLLqueue.h"
using namespace std
int choice=0,choice2=0;
int main()
{
int choice=0,choice2=0,i=0;
DoublyLinkedList<int> lst;
DLLstack stlist;
while(1)
{
choice2=0;
//ask user
cout<<"n1. Create Simple (Unsorted) Listn2. Create Sorted Listn";
cout<<"3. Create LIFO Queuen4. Create FIFO Queue(Stack)n";
cout<<"5. Exit Programn";
cout<<"Please choose an optionn";
cin>>choice;
while(choice==1)
{
//ask user 1.a
cout<<"n1. Enter integer for insertion at head of listn2. Enter integer for insertion at tail of listn";
cout<<"3. Display and Delete integer at headn4. Display and Delete integer at tailn";
cout<<"5. Search for integer in list and delete that noden6. Display Contents of list from head to tail in ordern7. Exitn";
cout<<"Please choose an optionn";
cin>>choice2;
if(choice2==1)//1.1
{cout<<"Enter integer to add to headn";
cin>>i;
lst.addToDLLHead(i);
}
if(choice2==2)//1.2
{
cout<<"Enter integer to add to tailn";
cin>>i;
lst.addToDLLTail(i);
}
if(choice2==3)//1.3
{ try{
i=lst.deleteFromDLLHead ();
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{cout<<"Empty Listn";
return(1);
}
}
cout<<"The deleted int was "<<i<<endl;
}
if(choice2==4)//1.4
{ try{
i=lst.deleteFromDLLTail ();
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{case 1:
cout<<"Empty Listn";
return(1);
}
}
cout<<"The deleted int was "<<i<<endl;
}
if(choice2==5)//1.5
{
cout<<"Enter Integer to search for and delete"<<endl;
cin>>i;
try{
lst.searchdelete (i);
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{cout<<"Empty Listn";
return(1);
}
}
}
if(choice2==6)
{lst.printlist ();}
if(choice2==7) choice=0;
}
while(choice==2)
{
//ask user 2.b
cout<<"n1. Enter integer for sorted insertion(increasing order) into listn2. Display and delete integer if present in listn";
cout<<"3. Display contents of sorted list of integers, in increasing ordern";
cout<<"4. Exit programn";
cout<<"Please choose an optionn";
cin>>choice2;
if(choice2==1)//2.1
{cout<<"Enter integer to add to the sorted list"<<endl;
cin>>i;
lst.addSorted (i);
}
if(choice2==2)
{
cout<<"Enter Integer to search for and delete"<<endl;
cin>>i;
try{
lst.searchdelete (i);
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{cout<<"Empty Listn";
return(1);
}
}
}
if(choice2==3)
{lst.printlist ();}
if(choice2=4)
{choice=0;}
}
while(choice==3)
{
cout<<"n1. ENQUEUEn2. DEQUEUEn";
cout<<"3. Print QUEUEn";
cout<<"4. Exit programn";
cout<<"Please choose an optionn";
cin>>choice2;
DLLQueue.qlst;
if(choice2==1)
{
cout<<"Enter number to place in Queue"<<endl;
cin>>i;
qlst.enqueue(i);}
if(choice2=2)
{try{qlst.dequeue();
} catch(int error_code)
{
cerr<<"Error: "<<error_code<<endl;
switch(error_code)
{cout<<"Empty Listn";
return(1);
}
}
}
if(choice2=3)
{lst.printlist ();}
if(choice2=4)
{choice=0;}
}
while(choice==4)
{
cout<<"n1. Pushn2. Popn";
cout<<"3. Print STACKn";
cout<<"4. Exit programn";
cout<<"Please choose an optionn";
cin>>choice2;
if(choice2==1)
{cout<<"Please enter value to place in stack"<<endl;
cin>>i;
stlst.push(i);
}
if(choice2==2)
{stlst.pop();}
if(choice2==3)
{lst.printlist ();}
if(choice2==4)
{choice=0;}
}
} //original while
return 0;
}
双链表.h
#ifndef DOUBLY_LINKED_LIST
#define DOUBLY_LINKED_LIST
#include <iostream>
using namespace std;
const int EMPTY_LIST=1;
template<class T>
class DLLNode
{
friend class DoublyLinkedList;
friend class DLLQueue;
friend class DLLstack;
public:
DLLNode(){next=prev=NULL;}
DLLNode(const T& el, DLLNode *n=NULL, DLLNode *p=NULL)
{info=el;
next=n;
prev=p;
}
T info;
DLLNode<T> *next, *prev;
protected:
//T info;
//DLLNode<T> *next, *prev;
private:
};
template<class T>
class DoublyLinkedList
{
friend class DLLQueue;
friend class DLLstack;
public:
DoublyLinkedList() {head=tail=NULL;} //good
void addToDLLTail(const T&); //good
T deleteFromDLLTail(); //good
T isDLLEmpty() {return (head==NULL);} //good
void addToDLLHead(const T&); //added
T deleteFromDLLHead(); //added
void deleteDLLNode(const T&); //added
bool isInList(const T&) const; //added
void addSorted(const T&); //added
void printlist(); //added
T searchdelete(const T&);
protected:
private:
DLLNode<T> *head, *tail;
};
template<class T>
T DoublyLinkedList<T>::deleteFromDLLTail(){
if(head!=NULL){
T el=tail->info;
if(head==tail){
delete tail;
head=tail=NULL;
}
return el;
}
else throw(EMPTY_LIST);
}
template<class T>
void DoublyLinkedList<T>::addToDLLTail(const T& el) {
if(tail!=NULL){
tail=new DLLNode<T>(el,NULL,tail);
tail->prev->next=tail;
}
else head=tail= new DLLNode<T>(el);
}
template<class T>
void DoublyLinkedList<T>::addToDLLHead (const T& el) {
head = new DLLNode<T>(el,head);
if(tail==NULL) tail=head;
}
template<class T>
T DoublyLinkedList<T>::deleteFromDLLHead (){
if(head!=NULL)
{
int el=head->info;
DLLNode<T> *tmp=head;
if(head==tail)
{head=tail=NULL;}
else{head=head->next;}
delete tmp;
return(el);
}
else throw(EMPTY_LIST);
}
template<class T>
void DoublyLinkedList<T>::deleteDLLNode(const T& el) {
if(head!=NULL){
if(head==tail&&el==head->info) {
delete head;
head=tail=NULL;
}
else if(el==head->info){
DLLNode<T> *tmp=head;
head=head->next;
head->prev=NULL;
delete tmp;
}
else {
DLLNode<T> *pred, *tmp;
for(tmp=head->next;tmp!=NULL && tmp->info!=el;tmp=tmp->next);
if(tmp!=NULL){
pred=tmp->prev;
pred->next=tmp->next;
pred->next->prev=pred;
if(tmp==tail) {tail=tail->prev;}
delete tmp;
}
}
}
else throw(EMPTY_LIST);
}
template<class T>
bool DoublyLinkedList<T>::isInList(const T& el) const {
DLLNode<T> *tmp;
for(tmp=head;tmp!=NULL&&tmp->info !=el; tmp=tmp->next);
return (tmp !=NULL);
}
template<class T>
void DoublyLinkedList<T>::addSorted(const T& i) {
DLLNode<T> *tmp, *nxt;
for(tmp=head;tmp->info<i;tmp=tmp->next);
nxt=tmp->next;
tmp->next= new DLLNode<T> (i,nxt,tmp);
next->prev=tmp->next;
delete tmp;
delete nxt;
}
template<class T>
void DoublyLinkedList<T>::printlist() {
DLLNode<T> *tmp;
if(head!=NULL){
for(tmp=head;tmp->next!=NULL;tmp=tmp->next){
cout<<tmp->info<<endl;
}
}
}
template<class T>
T DoublyLinkedList<T>::searchdelete(const T& i)
{ DLLNode<T> *tmp;
for(;tmp->info!=i&&tmp!=NULL;tmp=tmp->next){}
delete DLLNode<T> (tmp);
return(cout<<"Value Deleted from Listn");
}
#endif // DOUBLY_LINKED_LIST
DLL堆栈.h
#ifndef _DLLSTACK_H_
#define _DLLSTACK_H_
#include <iostream>
using namespace std;
#include "doubly-linked-list.h"
class DLLstack
{
friend class<class T> DoublyLinkedList;
friend class<class T> DLLNode;
public:
DLLstack(){};
bool isEmpty() const
{return lst.isEmpty();}
void clear()
{
while(!list.isEmpty()){
lst.deleteFromDLLHead();}
}
int pop()
{return (lst.deleteFromHead();}
void push(const int& el);
{lst.addToDLLHead (el);}
int topEl()
{
int topelement;
topelement=lst.deleteFromDLLHead ();
lst.addToDLLHead (topelement);
return(topelement);
}
protected:
private:
DoublyLinkedList stlst;
};
#endif // _DLLSTACK_H_
DLL队列.h
#ifndef _DLLQUEUE_H_
#define _DLLQUEUE_H_
#include <iostream>
using namespace std;
#include "doubly-linked-list.h"
template<class T>
class DLLQueue
{
friend <class T> class DoublyLinkedList
friend <class T> class DLLNode
public:
DLLQueue(){};
bool isEmpty() const
{ return lst.isEmpty();}
void enqueue(const T& el)
{ lst.addToDLLTail (el);}
T dequeue()
{ return {lst.deleteFromDLLHead ();}
T firstEl()
{
T front_el;
front_el=lst.deleteFromDLLHead ();
lst.addToDLLHead (front_el);
return(front_el);
}
~DLLQueue() {clear();}
protected:
private:
DoublyLinkedList qlst;
};
#endif // _DLLQUEUE_H_
现在我得到了30个错误,但我的主要问题(我认为(是它说我的DLLqueue.h文件和DLLstack.h文件中的友元函数声明是DLL队列.h:11:9:错误:"<"之前应为不合格的id代币DLL堆栈.h:11:14:错误:"<"之前应为标识符代币
以及堆栈和队列类中的lst对象"未在此范围内声明">
双重链接列表。h:141:2:错误:未在此作用域中声明"next">
还有更多的错误,但我认为这些是造成主要问题的原因,我需要先解决这些问题才能继续。
如果你想知道我在Ubuntu 的Ajuta IDE中编程
friend <class T> class DoublyLinkedList
应该是
template <class U> friend class DoublyLinkedList;
或
friend class DoublyLinkedList<T>;
取决于哪些实例化实际上需要成为朋友;其他朋友声明也是如此。
DoublyLinkedList qlst;
应该是
DoublyLinkedList<T> qlst;
因为DoublyLinkedList
是模板而不是类型。
在DLLStack::push
:中,函数体之前不应该有分号
void push(const int& el);
{lst.addToDLLHead (el);}
您有一个不需要的(
,在DLLstack::pop
:中没有匹配的)
{return (lst.deleteFromDLLHead();}
以及DLLQueue::deque
:中不需要的{
{ return {lst.deleteFromDLLHead ();}
有各种类型的拼写错误(例如,声明一个成员stlst
并将其称为lst
和list
(-编译器错误会直接指向这些错误。
DoublyLinkedList::isDLLEmpty
需要声明为const
,这样就可以从其他类的const
成员函数中调用它(一旦修复了调用它isEmpty
的拼写错误(。
在DoublyLinkedList::searchdelete
中,delete DLLNode<T>(tmp)
应该只是delete tmp
。您还需要修复已删除节点两侧节点中的指针,并返回类型为T
(可能是i
(的值,并修复循环的行为,使其真正搜索正确的节点(实际上,它迭代到最后,然后删除空指针,结果是什么都不做(。
最后,~DLLQueue
尝试调用不存在的DoublyLinkedList::clear
。您应该实现其中一个,或者实现DoublyLinkedList
的析构函数(或者两者都实现(。事实上,该列表是内存泄漏。它还应该有一个复制构造函数和赋值运算符(如果您不希望类是可复制的,则简单地声明为private(。
此外,您不应该使用保留名称(以下划线开头,如_DLLQUEUE_H_
(作为包含保护。您也不应该将using namespace std;
放在头文件中;头文件的用户可能不希望全局命名空间被污染。
将好友声明更改为
template <class U> friend class DLLNode;
这里也缺少分号
class DLLQueue
{
friend <class T> class DoublyLinkedList
friend <class T> class DLLNode
- 不要编写自己的列表、堆栈或队列。将
std::deque
与std::stack
和std::queue
适配器一起使用 - 永远不要在标题中执行
using namespace std
- 你所有的朋友声明都使用了错误的语法。它应该是
template <typename T> friend class X;
(或者使用class
而不是typename
(。此外,标识符区分大小写,DLLStack
和DLLstack
是两个完全不同的东西 - 您的类在复制时无法正常工作
- 不要抛出int,而是使用
std::exception
的适当子类 - 在成员变量定义中不使用模板参数
我看不到更多的大问题,但我可能在所有指针的东西中遗漏了一些东西。
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- (C++)分析树以计算返回错误值的简单算术表达式
- Project Euler问题4的错误解决方案
- 我的字符计数代码计算错误.为什么
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 尝试导入pybind-opencv模块时出现libgtk错误
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 在某些循环内使用vector.push_back时出现分段错误
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 错误:未在此范围内声明'reverse'