Clion c++ 中友元函数的错误
Errors with friend function in Clion c++
我写了一个小代码来练习数据结构和漂亮的C++。
如果将 SNode
中的变量更改为 public 并删除 friend class ...
行,则下面的代码可以完全正常工作。但是,根据我正在阅读的教科书,这应该可以正常工作。
我得到的错误如下:
line 11: error: ‘SLinkedList’ is not a class template
- 在“class SNode”的实例化中:
line 10: error: template argument required for ‘class SLinkedList’
- 在‘void SLinkedList::addFront(const E&) [with E = int]’的实例化中:
line 9: error: ‘int SNode<int>::elem’ is private
下面是用 Clion 编写的代码:
#include <iostream>
using namespace std;
template <typename E>
class SNode {
private:
E elem; //line 9
SNode<E> * next; // line 10
friend class SLinkedList<E>; //Provide SLinkedList access to these private variables (line 11)
};
template <typename E>
class SLinkedList {
public:
SLinkedList();
~SLinkedList();
bool empty() const;
const E& front() const;
void addFront(const E& e);
void removeFront();
void printAll() const;
private:
SNode<E> * head;
};
template <typename E>
SLinkedList<E>::SLinkedList():head(NULL){};
template <typename E>
bool SLinkedList<E>::empty() const {
return (head==NULL);
}
template <typename E>
void SLinkedList<E>::addFront(const E &e) {
SNode<E> * node = new SNode<E>;
node->elem=e;
node->next=head;
head=node;
}
template <typename E>
void SLinkedList<E>::removeFront() {
SNode<E> * temp = head;
head = head->next;
delete temp;
}
template <typename E>
const E& SLinkedList<E>::front() const {
return head->elem;
}
template <typename E>
SLinkedList<E>::~SLinkedList() {
while (!empty()){
removeFront();
}
}
template <typename E>
void SLinkedList<E>::printAll() const {
SNode<E> * itr =head;
while (itr != NULL){
cout<<itr->elem<<" ";
itr = itr->next;
}
}
int main() {
cout << "Hello, World!" << endl;
SLinkedList<int> test ;
test.addFront(2);
test.addFront(3);
test.addFront(6);
test.addFront(8);
test.addFront(19);
test.printAll();
return 0;
}
friend class SLinkedList<E>;
此模板尚未声明。从源文件的开头到结尾,您的 C++ 代码会以有序的方式进行编译。在稍后在此头文件中声明此模板之前,编译器不知道这是什么。
解决方法很简单:在头文件开头添加前向声明,因为SNode
模板声明:
template <typename E> class SLinkedList;
template <typename E>
class SNode {
private:
E elem;
SNode<E> * next;
friend class SLinkedList<E>;
};
friend class SLinkedList<E>;
此时 SLinkedList
还没有定义为模板,因此报错。给SLinkedList
一个前向声明,一切都会好起来的
添加这个:-
template <typename E>
class SLinkedList;
我写了一个小代码来练习数据结构和漂亮的C++。
如果将 SNode
中的变量更改为 public 并删除 friend class ...
行,则下面的代码可以完全正常工作。但是,根据我正在阅读的教科书,这应该可以正常工作。
我得到的错误如下:
line 11: error: ‘SLinkedList’ is not a class template
- 在“class SNode”的实例化中:
line 10: error: template argument required for ‘class SLinkedList’
- 在‘void SLinkedList::addFront(const E&) [with E = int]’的实例化中:
line 9: error: ‘int SNode<int>::elem’ is private
下面是用 Clion 编写的代码:
#include <iostream>
using namespace std;
template <typename E>
class SNode {
private:
E elem; //line 9
SNode<E> * next; // line 10
friend class SLinkedList<E>; //Provide SLinkedList access to these private variables (line 11)
};
template <typename E>
class SLinkedList {
public:
SLinkedList();
~SLinkedList();
bool empty() const;
const E& front() const;
void addFront(const E& e);
void removeFront();
void printAll() const;
private:
SNode<E> * head;
};
template <typename E>
SLinkedList<E>::SLinkedList():head(NULL){};
template <typename E>
bool SLinkedList<E>::empty() const {
return (head==NULL);
}
template <typename E>
void SLinkedList<E>::addFront(const E &e) {
SNode<E> * node = new SNode<E>;
node->elem=e;
node->next=head;
head=node;
}
template <typename E>
void SLinkedList<E>::removeFront() {
SNode<E> * temp = head;
head = head->next;
delete temp;
}
template <typename E>
const E& SLinkedList<E>::front() const {
return head->elem;
}
template <typename E>
SLinkedList<E>::~SLinkedList() {
while (!empty()){
removeFront();
}
}
template <typename E>
void SLinkedList<E>::printAll() const {
SNode<E> * itr =head;
while (itr != NULL){
cout<<itr->elem<<" ";
itr = itr->next;
}
}
int main() {
cout << "Hello, World!" << endl;
SLinkedList<int> test ;
test.addFront(2);
test.addFront(3);
test.addFront(6);
test.addFront(8);
test.addFront(19);
test.printAll();
return 0;
}
friend class SLinkedList<E>;
此模板尚未声明。从源文件的开头到结尾,您的 C++ 代码会以有序的方式进行编译。在稍后在此头文件中声明此模板之前,编译器不知道这是什么。
解决方法很简单:在头文件开头添加前向声明,因为SNode
模板声明:
template <typename E> class SLinkedList;
template <typename E>
class SNode {
private:
E elem;
SNode<E> * next;
friend class SLinkedList<E>;
};
friend class SLinkedList<E>;
此时 SLinkedList
还没有定义为模板,因此报错。给SLinkedList
一个前向声明,一切都会好起来的
添加这个:-
template <typename E>
class SLinkedList;