我已经搜索了很多这个问题的解决方案但是徒劳无功,所以我使用Eclipse IDE MARS(4.5.2)版本并且我一直在努力分离我的类标题和.cpp文件。
node.h
#ifndef NODE_H_
#define NODE_H_
template <typename T>
class node {
T key;
node<T> *next;
public:
node(T k, node<T> *a_node) : key(k), next(a_node) {}
T get_key() const;
void set_key(T key);
node<T>* get_next() const;
void set_next(node<T> *next);
~node();
};
#endif /* NODE_H_ */
node.cpp
#include <iostream>
#include "node.h"
template<typename T>
T node<T>::get_key() const {
return key;
}
template<typename T>
void node<T>::set_key(T key) {
this->key = key;
}
template<typename T>
node<T>* node<T>::get_next() const {
return next;
}
template<typename T>
void node<T>::set_next(node<T> *next) {
this->next = next;
}
template<typename T>
node<T>::~node() {
std::cout << "Node destructor" << std::endl;
}
singly_linked_list.h
#ifndef SINGLY_LINKED_LIST_H_
#define SINGLY_LINKED_LIST_H_
#include <iostream>
template <typename T> class node; // forward declare our template
template <typename T>
class linked_list {
node<T> *head;
node<T> *tail;
int num_elements;
public:
linked_list() : head(nullptr), tail(head), num_elements(0) {}; //O(1)
void push_front(T key); // O(1)
T top_front(); // O(1)
void pop_front(); // O(1)
void push_back(T key); // O(1)
T top_back(); // O(1)
void pop_back(); // O(n)
node<T> * find(T key); // O(n)
void erase(T key); // O(n) , only used to erase elements between front and back
void add_before(node<T> * const a_node,T key); // O(n)
void add_after(node<T> * const a_node,T key); // O(1) , finding the a_node takes O(n) by find method
bool empty(); // O(1)
void print(); // O(n)
int size(); // O(1)
~linked_list(); // O(n)
};
#endif /* SINGLY_LINKED_LIST_H_ */
singly_linked_list.cpp
template <typename T>
void linked_list<T>::push_front(T key) {
node<T> *new_node = new node<T> (key,nullptr);
if (head == nullptr) {
head = new_node;
tail = new_node ;
}else {
new_node->set_next(head);
head = new_node;
}
num_elements++;
}
template <typename T>
T linked_list<T>::top_front() {
if (head == nullptr) {
std::cerr << "Empty List!" << std::endl;
exit(-1);
} else {
return head->get_key();
}
}
template <typename T>
void linked_list<T>::pop_front() {
if (head == nullptr) {
std::cerr << "Empty List!" << std::endl;
exit(-1);
} else {
node<T> *temp = head;
head = temp->get_next();
delete temp;
temp = nullptr;
num_elements--;
}
if (head == nullptr) tail = head;
}
template<typename T>
void linked_list<T>::push_back(T key) {
node<T> *new_node = new node<T>(key,nullptr);
if (head == nullptr) {
head = new_node;
tail = new_node;
}else {
tail->set_next(new_node);
tail = new_node;
}
num_elements++;
}
template<typename T>
T linked_list<T>::top_back() {
if (head == nullptr) {
std::cerr << "Empty List!" << std::endl;
exit(-1);
}else {
return tail->get_key();
}
}
template<typename T>
void linked_list<T>::pop_back() {
if (head == nullptr) { // no elements
std::cerr << "Empty List!" << std::endl;
exit(-1);
}
if (head == tail) { // only one element
node<T> *temp = head;
head = nullptr;
tail = head;
delete temp;
num_elements--;
}else {
node<T> *temp = head;
while (temp->get_next()->get_next() != nullptr) {
temp = temp->get_next();
}
tail = temp;
tail->set_next(nullptr);
temp = temp->get_next();
delete temp;
num_elements--;
}
}
template <typename T>
bool linked_list<T>::empty() {
if ((head == nullptr) && (num_elements == 0)) {
return true;
} else {
return false;
}
}
template <typename T>
void linked_list<T>::print() {
if (head == nullptr) {
std::cerr << "Empty List!" << std::endl;
exit(-1);
} else {
node<T> *temp = head;
while(temp != nullptr) {
std::cout << temp->get_key() << " " ;
temp = temp->get_next();
}
std::cout << std::endl;
}
}
template<typename T>
int linked_list<T>::size() {
return num_elements;
}
template<typename T>
node<T>* linked_list<T>::find(T key) {
if (head == nullptr) {
std::cerr << "Empty List!" << std::endl;
exit(-1);
} else {
node<T> *temp = head;
while(temp != nullptr) {
if (temp->get_key() == key) {
return temp;
}
temp = temp->get_next();
}
}
return nullptr;
}
template<typename T>
void linked_list<T>::erase(T key) { // only used to erase elements between front and back
if (head == nullptr) {
std::cerr << "Empty List!" << std::endl;
exit(-1);
}else {
node<T> *temp = head;
if (head == tail) {
if (temp->get_key() == key) {
delete temp;
head = nullptr;
tail = head;
}
} else {
node<T> *pre;
while(temp != nullptr) {
if (temp->get_key() == key) {
break;
}
pre = temp;
temp = temp->get_next();
}
pre->set_next(temp->get_next());
delete temp;
}
}
}
template<typename T>
void linked_list<T>::add_before(node<T>* const a_node, T key) {
if (head == nullptr) {
std::cout << "head is null" << std::endl;
}else if (a_node == nullptr) {
std::cout << "the node doesn't exist" << std::endl;
}else {
node<T> * new_node = new node<T>(key,nullptr);
node<T> *temp = head;
while (temp->get_next() != a_node) {
temp = temp->get_next();
}
new_node->set_next(a_node);
temp->set_next(new_node);
if (head == a_node) {
head = new_node;
}
num_elements++;
}
}
template<typename T>
void linked_list<T>::add_after(node<T>* const a_node, T key) { // add after a node in the middle not the fron and the back
if (head == nullptr) {
std::cout << "head is null" << std::endl;
}else if (a_node == nullptr) {
std::cout << "the node doesn't exist" << std::endl;
}else {
node<T> * new_node = new node<T>(key,nullptr);
new_node->set_next(a_node->get_next());
a_node->set_next(new_node);
if (tail == a_node) {
tail = new_node;
}
num_elements++;
}
}
template<typename T>
linked_list<T>::~linked_list() {
node<T> *temp = head;
node<T> *temp_pre = temp;
while (temp->get_next() != nullptr) {
temp = temp->get_next();
delete temp_pre;
temp_pre = temp;
}
delete temp;
}
TEST.CPP
#include <iostream>
#include "singly_linked_list.h"
int main() {
linked_list<std::string> ll;
/* back operations */
ll.top_back();
ll.push_back("A");
return 0;
}
问题是linked_list类的所有方法都是未定义引用的,而所有header和cpp文件都在同一个项目中。非常感谢任何帮助。
修改
我尝试仅链接节点类,问题仍然存在。 链接器如下:
g++ -o Working.exe node.o singly_linked_list.o test_singly_linked_list.o