My code is working now. As you can see in the list.h
some type definitions are too long and hard to read. Is there a way to do some short ones? And what happens if the code throws an exception? (I know I will have leaking memory parts) What can I do to collect garbage? And what other functions might be added to code to enhance it?
list.h
#ifndef LIST_H_
#define LIST_H_
#include <iostream>
template <typename T>
class list{
public:
list();
~list();
class node;
typedef T value_type;
typedef T& reference;
typedef node node_type;
typedef node_type* node_pointer;
list& push_back(value_type);
value_type pop_front();
node_pointer begin() const;
private:
node_pointer head, tail;
};
template <typename T>
class list<T>::node{
public:
node(value_type value = 0);
~node();
void setData(value_type);
value_type getData() const;
void setNext(node_pointer);
node_pointer getNext() const;
private:
value_type data;
node_pointer ptr_next;
};
template <typename T>
inline list<T>::node::node(value_type value) : data(value), ptr_next(nullptr){
//std::cout << "*" << value << "\t";
}
template <typename T>
inline list<T>::node::~node(){
//std::cout << "node dtor" << std::endl;
}
template <typename T>
void list<T>::node::setData(value_type value){
this->data = value;
}
template <typename T>
typename list<T>::value_type list<T>::node::getData() const{
return this->data;
}
template <typename T>
void list<T>::node::setNext(node_pointer ptr){
this->ptr_next = ptr;
}
template <typename T>
typename list<T>::node_pointer list<T>::node::getNext() const{
return this->ptr_next;
}
template <typename T>
list<T>::list() : head(nullptr), tail(nullptr){
//std::cout << "list ctor" << std::endl;
}
template <typename T>
list<T>::~list(){
list<T>::node_pointer ptr = this->head, next_ptr;
while(ptr != nullptr){
//std::cout << "@" << ptr->getData() << "\t";
next_ptr = ptr->getNext();
delete ptr;
ptr = next_ptr;
}
}
template <typename T>
list<T>& list<T>::push_back(value_type value){
node_pointer item = new node_type(value);
if(this->tail) this->tail->setNext(item);
this->tail = item;
if(!this->head) this->head = this->tail;
return *this;
}
template <typename T>
typename list<T>::value_type list<T>::pop_front(){
if(this->head){
node_pointer item = this->head;
value_type value = this->head->getData();
this->head = this->head->getNext();
delete item;
return value;
}
return 0;
}
template <typename T>
typename list<T>::node_pointer list<T>::begin() const{
return this->head;
}
template <typename T>
std::ostream & operator<<(std::ostream &stream, list<T> &obj){
typename list<T>::node_pointer ptr = obj.begin();
while(ptr != nullptr){
stream << ptr->getData() << ' ';
ptr = ptr->getNext();
}
return stream;
}
#endif /* LIST_H_ */
main.cpp
int main (int argc, char ** argv){
list<int> numbers;
numbers.push_back(3).push_back(5).push_back(11);
cout << numbers;
return 0;
}