I have the following class:
template<class T>
struct Node {
Node<T>* next;
T data;
};
template<class T>
class LinkedList
{
private:
Node<T>* first;
Node<T>* last;
public:
LinkedList<T>() : first(NULL), last(NULL) {}
LinkedList<T>(const LinkedList& other)
{
operator=(other);
}
~LinkedList()
{
Node<T>* tmp = first->next;
while (!first)
{
tmp = first;
first = first->next;
free(tmp);
}
}
void add(const T& data) {
Node<T>* tmp = new Node<T>;
tmp->data = data;
tmp->next = NULL;
if (!first) {
first = tmp;
last = first;
}
else
{
last->next = tmp;
last = tmp;
}
}
Node<T>* getFirst() const
{
return first;
}
LinkedList<T>& operator=(const LinkedList<T>& other)
{
Node<T>* tmp = other.first;
while (tmp)
{
add(tmp->data);
tmp = tmp->next;
}
return *this;
}
LinkedList<T>& operator-=(T value)
{
while (first && first->data == value)
{
Node<T>* tmp = first;
first = first->next;
free(tmp);
}
for (Node<T>* curr = first; curr != NULL; curr = curr->next)
{
while (curr->next != NULL && curr->next->data == value)
{
Node<T>* tmp = curr->next;
if (tmp == last)
{
last = curr;
}
curr->next = tmp->next;
free(tmp);
}
}
return *this;
}
LinkedList<T>& operator+=(const T& value)
{
add(value);
return *this;
}
T get(int index) {
if (index == 0) {
return this->first->data;
}
else {
Node<T>* curr = this->first;
for (int i = 0; i < index; ++i) {
curr = curr->next;
}
return curr->data;
}
}
T operator[](int index) {
return get(index);
}
bool isInList(T value)
{
Node<T>* tmp = first;
while (tmp)
{
if (tmp->data == value)
return true;
tmp = tmp->next;
}
return false;
}
};
This current template implementation does not support the char* type, so I want to add a template specialization for the char* type.
Adding the following specialization:
template <>
LinkedList<char*>& LinkedList<char*>::operator+=(const char*& value)
{
}
gives the following error:
Error C2244 'LinkedList<char *>::operator +=': unable to match function definition to an existing declaration
How can I fix it?
Related
I am trying to write a playlist method for songs in c++, however, I keep running into frequent errors.
template <typename T>
struct cir_list_node
{
T* data;
cir_list_node *next, *prev;
//destructor
~cir_list_node() {
delete data;
}
};
template <typename T>
struct cir_list
{
public:
using node = cir_list_node<T>; // renaiming for local use
using node_ptr = node*;
private:
node_ptr head;
size_t n;
public:
// basic constructor and size function
cir_list(): n(0) // initiator list
{
head = new node(NULL,NULL,NULL); //dummy node
head->next = head; // circular list wraps around
head->prev = head;
}
cir_list(const cir_list& other): cir_list()
{
// insert in reverse order (okay because list is circular)
for(const auto& i : other)
insert(i);
}
cir_list(const std::initializer_list<T>& il): head(NULL), n(0)
{
//insert in reverse order
for(const auto& i : il)
insert(i);
}
~cir_list()
{
while(size())
{
erase(head->data);
}
}
size_t size() const
{
return n;
}
void insert(const T& value)
{
node_ptr newNode = new node(new T(value),NULL,NULL);
n++;
auto dummy = head->prev;
dummy->next = newNode;
newNode->prev = dummy;
if(head == dummy) {
dummy->prev = newNode;
newNode->next = dummy;
head = newNode;
return;
}
newNode->next = head;
head->prev = newNode;
head = newNode;
return;
}
void erase(const T& value)
{
auto cur = head, dummy = head->prev;
while (cur != dummy){
if(*(cur->data) == value){
cur->prev->next = cur->next;
cur->next->prev = cur->prev;
if(cur == head)
head = head->next;
delete cur;
n--;
return;
}
cur = cur->next;
}
}
struct cir_list_it
{
private:
node_ptr ptr;
public:
cir_list_it(node_ptr p) : ptr(p)
{}
T& operator*()
{
return *(ptr->data);
}
node_ptr get()
{
return ptr;
}
cir_list_it& operator++() // prefix
{
ptr = ptr->next;
return *this;
}
cir_list_it operator++(int) // postfix
{
cir_list_it it = *this;
++(*this);
}
cir_list_it& operator--() //prefix
{
ptr = ptr->prev;
return *this;
}
cir_list_it operator--(int) // postfix
{
cir_list_it it = *this;
--(*this);
return it;
}
friend bool operator == (const cir_list_it& it1, const cir_list_it& it2)
{
return it1.ptr == it2.ptr;
}
friend bool operator != (const cir_list_it& it1, const cir_list_it& it2)
{
return it1.ptr != it2.ptr;
}
};
cir_list_it begin()
{
return cir_list_it {head};
}
cir_list_it end()
{
return cir_list_it {head->prev};
}
cir_list_it end() const
{
return cir_list_it{head->prev};
}
};
struct playlist
{
cir_list<int> list;
void insert(int song)
{
list.insert(song);
}
void erase(int song)
{
list.erase(song);
}
void loopOnce()
{
for(auto& song : list){
std::cout << song << " ";
}
std::cout << std::endl;
}
};
int main()
{
playlist pl;
pl.insert(1);
pl.insert(2);
std::cout << "Playlist: ";
pl.loopOnce();
playlist pl2 = pl;
pl2.erase(2);
pl2.insert(3);
std::cout << "Second playlist";
pl2.loopOnce();
}
Errors
1 and 2:
3 and 4:
It seems there is a typo
struct cir_list_node
{
T* data;
cir_list_node *next, *prev;
//destructor
~cir_list_node() {
delete data;
}
};
You forgot to prefix this declaration with
template <typename T>
This template structure declaration declares an aggregate.
You can not initialized it with an expression inside parentheses like
head = new node(NULL,NULL,NULL);
Instead you need to write using braces
head = new node { NULL, NULL, NULL };
or as you are writing a C++ program then
head = new node { nullptr, nullptr, nullptr };
It seems there is a typo
struct cir_list_node
{
T* data;
cir_list_node *next, *prev;
//destructor
~cir_list_node() {
delete data;
}
};
New to c++ and I'm having trouble implementing an Iterator class in my LinkedList. I have a Iterator class defined in the private section of my LinkedList class as follows:
cs_linked_list.h
#ifndef LINKED_LIST_H_
#define LINKED_LIST_H_
#include <initializer_list>
#include <iostream>
namespace cs {
template <typename T>
class LinkedList {
struct Node; // forward declaration for our private Node type
public:
/**Constructs an empty list.**/
LinkedList(){
head_ = nullptr;
}
/**
* #brief Constructs a list from a range.
*
*/
template <class InputIterator>
LinkedList(InputIterator first, InputIterator last) {
for (; first != last; ++first) this->push_back(*first);
}
/** Constructs a list with a copy of each of the elements in `init_list`, in the same order. */
LinkedList(std::initializer_list<T> init_list) {
this->operator=(init_list); // call initializer list assignment
}
/**Constructs a container with a copy of each of the elements in another, in the same order**/
LinkedList(const LinkedList<T>& another){
//TODO
this->operator=(another);
}
/** Destroys each of the contained elements, and deallocates all memory allocated by this list. */
~LinkedList() {
while (this->head_) {
Node* old_head = this->head_;
this->head_ = old_head->next;
delete old_head;
}
}
/**Returns the number of elements in this list.Node *head**/
size_t size() const{ //DONE
//TODO
Node *temp = head_;
size_t len = 0;
while (temp != nullptr){
len++;
temp = temp->next;
}
return len;
}
/**Returns whether the list container is empty (that is, whether its size is 0). **/
bool empty() const{ //DONE
if(size_ == 0){
return true;
} else{
return false;
}
}
/** Appends a copy of `val` to this list. */
void push_back(const T& val) {
Node* new_node = new Node{val};
if (this->size_ == 0) {
this->head_ = this->tail_ = new_node;
} else {
this->tail_->next = new_node;
new_node->prev = this->tail_;
this->tail_ = new_node;
}
++this->size_;
}
/** Prepends a copy of `val` to this list. */
void push_front(const T& val) {
Node* new_node = new Node{val};
if (this->size_ == 0) {
this->head_ = this->tail_ = new_node;
} else {
new_node->next = this->head_;
this->head_->prev = new_node;
this->head_ = new_node;
}
++this->size_;
}
/**Returns a reference to the value in the first element in this list.**/
T& front() const{
return head_->data;
}
/**Returns a reference to the value in the last element in this list. **/
T& back() const{
return tail_->data;
}
/**Deletes the first value in this list. **/
void pop_front(){
Node *temp = head_;
if(empty()){
return;
}
if(temp == tail_){
return;
}
head_ = head_->next;
if (head_ != nullptr) {
head_->prev = nullptr;
} else {
tail_ = nullptr;
}
delete temp;
}
/**Deletes the last value in this list**/
void pop_back(){
if(empty()){
return;
}
if(head_ == tail_){
return;
}
Node *temp = head_;
while(temp->next->next != nullptr){
temp = temp->next;
}
tail_ = temp;
delete tail_->next;
tail_->next = nullptr;
size_--;
}
/**resizes the list so that it contains n elements.**/
void resize(std::size_t n){
//TODO
for (size_t i = 0; i < n; i++){
push_back('\0');
}
}
/**resizes the list so that it contains n elements**/
void resize(std::size_t n, const T &fill_value){
//TODO
for (size_t i = 0; i < n; i++) {
push_back(fill_value);
}
}
/**Removes from the container all the elements that compare equal to val. **/
void remove(const T &val){
//TODO
Node *p1 = head_;
Node *p2 = nullptr;
if(p1 != nullptr && p1->data == val){
head_ = p1->next;
delete p1;
} else {
while (p1 != nullptr && p1->data != val){
p2 = p1;
p1 = p1->next;
}
if (p1 == nullptr) {
return;
}
p2->next = p1->next;
delete p1;
}
}
/**Removes duplicate values from this list**/
void unique(){
//TODO
Node *temp = head_;
while (temp != nullptr && temp->next != nullptr) {
Node *temp2 = temp;
while (temp2->next != nullptr) {
if (temp->data == temp2->next->data) {
Node *temp3 = temp2->next;
temp2->next = temp2->next->next;
delete temp3;
} else {
temp2 = temp2->next;
}
}
temp = temp->next;
}
}
/**Deletes all values in this list.**/
void clear(){
//TODO
while (head_ != nullptr){
Node *temp = head_;
head_ = head_->next;
delete temp;
}
tail_ = nullptr;
size_ = 0;
}
/**Reverses the order of the elements in this list.**/
void reverse(){
//TODO
Node *p1 = head_;
Node *p2 = nullptr;
while (p1 != nullptr) {
Node *temp = p1->next;
p1->next = p2;
p2 = p1;
p1 = temp;
}
head_ = p2;
}
/** Replaces the contents of this list with a copy of each element in `init_list`. */
LinkedList& operator=(std::initializer_list<T> init_list) {
this->size_ = 0;
for (auto&& val : init_list)
this->push_back(val);
return *this;
}
/**Replaces the contents of this list with a copy of each element in another, in the same order.**/
LinkedList& operator=(const LinkedList& another){
//TODO
if (this != &another) {
this->clear();
Node *temp = another.head_;
this->size_ = 0;
while (temp) {
this->push_back(temp->data);
temp = temp->next;
}
}
return *this;
}
/**Compares this list with another for equality.**/
bool operator==(const LinkedList &another){ //DONE
//TODO
auto comp = head_;
auto comp2 = another.head_;
while(comp != nullptr){
if(comp != comp2){
return false;
}
comp = comp->next;
comp2 = comp2->next;
}
return true;
}
/**Compares this list with another for inequality. **/
bool operator!=(const LinkedList &another){ //DONE
//TODO
auto comp = head_;
auto comp2 = another.head_;
while(comp != nullptr){
if(comp != comp2){
return true;
}
comp = comp->next;
comp2 = comp2->next;
}
return false;
}
/** Inserts this list into an ostream, with the format `[element1, element2, element3, ...]` */
friend std::ostream& operator<<(std::ostream& out, const LinkedList& list) {
out << '[';
for (Node* cur = list.head_; cur; cur = cur->next) {
out << cur->data;
if (cur->next)
out << ", ";
}
out << ']';
return out;
}private:
struct Node {
T data;
Node* next = nullptr;
Node* prev = nullptr;
};
Node* head_ = nullptr;
Node* tail_ = nullptr;
std::size_t size_ = 0;
class Iterator {
public:
using iterator_category = std::bidirectional_iterator_tag;
using value_type = T;
using difference_type = int;
using pointer = T*;
using reference = T&;
// Default constructor
Iterator() {
//TODO
n = nullptr;
}
// Copy constructor
Iterator(const Iterator& other) {
//TODO
this->operator=(other);
}
//Destructor if needed
~Iterator() {
//TODO
while (this->list.head_){
Node *old_head = this->list.head_;
this->list.head_ = old_head->next;
delete old_head;
}
}
// Copy assign
Iterator& operator=(const Iterator& that) {
//TODO
if(this != &that){
this->list.clear();
Node *temp = that.list.head_;
this->list.size_ = 0;
while (temp){
this->list.push_back(temp->data);
temp = temp->next;
}
}
return *this;
}
// Prefix increment
Iterator& operator++() {
//TODO
this->n = this->n->next;
return *this;
}
// Postfix increment
Iterator operator++(int) {
Iterator tmp(*this);
this->operator++();
return tmp;
}
// Prefix decrement
Iterator& operator--() {
//TODO
this->n = this->n->prev;
return *this;
}
// Postfix decrement
Iterator operator--(int) {
Iterator tmp(*this);
this->operator--();
return tmp;
}
// Inequality
bool operator!=(Iterator that) const {
return !(this->operator==(that));
}
// Equality
bool operator==(Iterator that) const {
//TODO
auto temp = list.head_;
auto temp2 = that.list.head_;
while(temp != nullptr){
if(*temp != *temp2){
return false;
}
temp = temp->next;
temp2 = temp2->next;
}
return true;
}
// lvalue dereference
T& operator*() const {
//TODO
return this->n->data;
}
// referring
Iterator* operator->() const {
return this;
}
Iterator begin(){
//TODO
return Iterator(list.head_->next);
}
Iterator end(){
//TODO
return Iterator(list.tail_);
}
private:
Node *n;
LinkedList<T> list;
};
};
} // namespace cs
#endif // LINKED_LIST_H_
Main:
#include "cs_linked_list.h"
#include <iostream>
int main() {
/***TESTING***/
cs::LinkedList<int> list;
// Add few items to the end of LinkedList
list.push_back(1);
list.push_back(2);
list.push_back(3);
std::cout << "Traversing LinkedList through Iterator" << std::endl;
for ( cs::LinkedList<int>::Iterator iter = list.begin();iter != list.end(); iter++) {
std::cout << *iter << " ";
}
std::cout << std::endl;
return 0;
}
Since my Iterator class is private I can't seem to implement my Begin() and End() functions. Should I Make it public or am I missing one crucial step. Instructions say to define a Iterator class in the private section of my LinkedList class.
So I am attempting to create a Linked List that can store books for a imaginative library. Within the linked list, each node should contain the branch of library, the author's name, the book's title, and the number of copies of said book.
I'm having difficulty creating a linked list with multiple fields per node. How would I go about it so that each node can store 3 separate strings and an integer, and then finally, a pointer to the next node?
Here is my current code.
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include <stdexcept>
using namespace std;
template<typename T>
class Node
{
public:
T element;
Node<T>* next;
Node()
{
next = nullptr;
}
Node(T element) // Constructor
{
this->element = element;
next = nullptr;
}
};
template<typename T>
class Iterator : public std::iterator<std::forward_iterator_tag, T>
{
public:
Iterator(Node<T>* p)
{
current = p;
}
Iterator operator++() // Prefix ++
{
current = current->next;
return *this;
}
Iterator operator++(int dummy) // Postfix ++
{
Iterator temp(current);
current = current->next;
return temp;
}
T& operator*()
{
return current->element;
}
bool operator==(const Iterator<T>& iterator)
{
return current == iterator.current;
}
bool operator!=(const Iterator<T>& iterator)
{
return current != iterator.current;
}
private:
Node<T>* current;
};
template<typename T>
class LinkedList
{
public:
LinkedList();
LinkedList(const LinkedList<T>& list);
virtual ~LinkedList();
void addFirst(T element);
void addLast(T element);
T getFirst() const;
T getLast() const;
T removeFirst() throw (runtime_error);
T removeLast();
void add(T element);
void add(int index, T element);
void clear();
bool contains(T element) const;
T get(int index) const;
int indexOf(T element) const;
bool isEmpty() const;
int lastIndexOf(T element) const;
void remove(T element);
int getSize() const;
T removeAt(int index);
T set(int index, T element);
Iterator<T> begin() const
{
return Iterator<T>(head);
}
Iterator<T> end() const
{
return Iterator<T>(tail->next);
}
private:
Node<T>* head;
Node<T>* tail;
int size;
};
template<typename T>
LinkedList<T>::LinkedList()
{
head = tail = nullptr;
size = 0;
}
template<typename T>
LinkedList<T>::LinkedList(const LinkedList<T>& list)
{
head = tail = nullptr;
size = 0;
Node<T>* current = list.head;
while (current != nullptr)
{
this->add(current->element);
current = current->next;
}
}
template<typename T>
LinkedList<T>::~LinkedList()
{
clear();
}
template<typename T>
void LinkedList<T>::addFirst(T element)
{
Node<T>* newNode = new Node<T>(element);
newNode->next = head;
head = newNode;
size++;
if (tail == nullptr)
tail = head;
}
template<typename T>
void LinkedList<T>::addLast(T element)
{
if (tail == nullptr)
{
head = tail = new Node<T>(element);
}
else
{
tail->next = new Node<T>(element);
tail = tail->next;
}
size++;
}
template<typename T>
T LinkedList<T>::getFirst() const
{
if (size == 0)
throw runtime_error("Index out of range");
else
return head->element;
}
template<typename T>
T LinkedList<T>::getLast() const
{
if (size == 0)
throw runtime_error("Index out of range");
else
return tail->element;
}
template<typename T>
T LinkedList<T>::removeFirst() throw (runtime_error)
{
if (size == 0)
throw runtime_error("No elements in the list");
else
{
Node<T>* temp = head;
head = head->next;
if (head == nullptr) tail = nullptr;
size--;
T element = temp->element;
delete temp;
return element;
}
}
template<typename T>
T LinkedList<T>::removeLast()
{
if (size == 0)
throw runtime_error("No elements in the list");
else if (size == 1)
{
Node<T>* temp = head;
head = tail = nullptr;
size = 0;
T element = temp->element;
delete temp;
return element;
}
else
{
Node<T>* current = head;
for (int i = 0; i < size - 2; i++)
current = current->next;
Node<T>* temp = tail;
tail = current;
tail->next = nullptr;
size--;
T element = temp->element;
delete temp;
return element;
}
}
template<typename T>
void LinkedList<T>::add(T element)
{
addLast(element);
}
template<typename T>
void LinkedList<T>::add(int index, T element)
{
if (index == 0)
addFirst(element);
else if (index >= size)
addLast(element);
else
{
Node<T>* current = head;
for (int i = 1; i < index; i++)
current = current->next;
Node<T>* temp = current->next;
current->next = new Node<T>(element);
(current->next)->next = temp;
size++;
}
}
template<typename T>
void LinkedList<T>::clear()
{
while (head != nullptr)
{
Node<T>* temp = head;
head = head->next;
delete temp;
}
tail = nullptr;
size = 0;
}
template<typename T>
T LinkedList<T>::get(int index) const
{
if (index < 0 || index > size - 1)
throw runtime_error("Index out of range");
Node<T>* current = head;
for (int i = 0; i < index; i++)
current = current->next;
return current->element;
}
template<typename T>
int LinkedList<T>::indexOf(T element) const
{
// Implement it in this exercise
Node<T>* current = head;
for (int i = 0; i < size; i++)
{
if (current->element == element)
return i;
current = current->next;
}
return -1;
}
template<typename T>
bool LinkedList<T>::isEmpty() const
{
return head == nullptr;
}
template<typename T>
int LinkedList<T>::getSize() const
{
return size;
}
template<typename T>
T LinkedList<T>::removeAt(int index)
{
if (index < 0 || index >= size)
throw runtime_error("Index out of range");
else if (index == 0)
return removeFirst();
else if (index == size - 1)
return removeLast();
else
{
Node<T>* previous = head;
for (int i = 1; i < index; i++)
{
previous = previous->next;
}
Node<T>* current = previous->next;
previous->next = current->next;
size--;
T element = current->element;
delete current;
return element;
}
}
// The functions remove(T element), lastIndexOf(T element),
// contains(T element), and set(int index, T element) are
// left as an exercise
#endif
Given a struct, such as
struct Book
{
std::string branch;
std::string author;
std::string title;
int copies;
};
A LinkedList<Book> would have all the data elements you want in each Node.
so I have this code for linked list below. I need to create copy/move constructors and operators.
I am having troubles how to make it the right way.
I know the code isn't perfect, I will appreciate all tips, but I want to focus mainly on copy/move semantic.
#include <iostream>
#include <string>
#include <stdexcept>
using namespace std;
class List {
class Node {
Node* next;
string text;
int index;
friend class List;
public:
Node(const string& value, int i) : next(nullptr), index(i), text(value) {}
friend ostream& operator<< (ostream& wy, const Node& wzl) {
if (wzl.next) return wy << wzl.text << ", " << *wzl.next;
else return wy << wzl.text;
}
};
Node* head;
int _size(Node* node, int size = 0) {
if (node == NULL) {
return size;
} else {
_size(node->next, size+1);
}
}
void _insert(Node* node, const string& value, int index) {
if (node->next == NULL || node->next->index > index) {
if (node->index == index) {
node->text = value;
} else {
Node* element = new Node(value, index);
element->next = node->next;
node->next = element;
}
} else {
_insert(node->next, value, index);
}
}
string _read(Node* node, int index) {
if (node->next != NULL && node->next->index <= index) {
return _read(node->next, index);
} else if (node->index == index) {
return node->text;
} else {
throw invalid_argument("No such index");
}
}
void _remove(Node* node, int index) {
if (node->next != NULL && node->next->index < index) {
_remove(node->next, index);
} else if (node->next->index == index) {
Node* temp;
if (node->next->next != NULL) {
int temp_index = node->next->next->index;
temp = new Node(node->next->next->text, temp_index);
if (node->next->next->next != NULL) {
temp->next = node->next->next->next;
} else {
temp->next = NULL;
}
temp->index = node->next->next->index;
} else {
temp = nullptr;
}
delete node->next;
node->next = temp;
} else {
throw invalid_argument("No such index");
}
}
public:
List() : head(nullptr){};
List(const List &lst) : head(nullptr) {
Node* tmp_lst = lst.head;
Node* tmp_this = this->head;
while (tmp_lst != NULL) {
// cerr << this->head->text;
tmp_this = new Node(tmp_lst->text, tmp_lst->index);
tmp_this = tmp_this->next;
tmp_lst = tmp_lst->next;
}
}
List(List&& lst);
List(initializer_list<string> lst) : List() {
Node* tmp;
int pos = 0;
for (auto element : lst) {
if (this->head != NULL){
tmp->next = new Node(element, pos);
tmp = tmp->next;
pos++;
} else {
this->head = new Node(element, pos);
tmp = this->head;
pos++;
}
}
};
List& operator= (const List& lst) {
if (this != &lst) {
delete this->head;
this->head = nullptr;
Node* tmp_lst = lst.head;
Node* tmp_this = this->head;
while (tmp_lst != NULL) {
tmp_this = new Node(tmp_lst->text, tmp_lst->index);
tmp_this = tmp_this->next;
tmp_lst = tmp_lst->next;
}
}
return *this;
}
List& operator= (List&& lst);
~List(){
delete head;
};
void insert(const string& value, int pos) {
if (pos < 0) {
throw invalid_argument("Position cant be negative");
}
if (this->head == NULL) {
Node* new_head = new Node(value, pos);
this->head = new_head;
} else if (this->head->index > pos) {
Node* new_head = new Node(value, pos);
new_head->next = this->head;
this->head = new_head;
} else {
_insert(this->head, value, pos);
}
}
string read(int pos) {
return _read(this->head, pos);
}
int size() {
return _size(this->head);
}
void remove(int pos) {
return _remove(this->head, pos);
}
public:
friend ostream& operator<< (ostream& wy, const List& lst) {
if (lst.head) return wy << "(" << *lst.head << ")";
else return wy << "()";
}
};
int main() {
return 0;
}
You List copy-constructor is severely flawed:
You initialize tmp_this to the value of this->head which is a null pointer
The above doesn't matter because the first thing you do in the loop is reassign tmp_this to point to a new Node object.
Then you immediately discard that pointer, by reassigning tmp_this to point to tmp_this->next which is a null pointer.
And you don't link anything into the list.
A working function could look something like
List(const List &lst) : head(nullptr) {
Node* tmp_lst = lst.head;
Node** tmp_current = &head;
while (tmp_lst != NULL) {
Node* tmp_this = new Node(tmp_lst->text, tmp_lst->index);
// Would prefer to use the copy-constructor here too, instead of the above
// Node* tmp_this = new Node(tmp_lst);
// This links the new node into the end of the list
*tmp_current = tmp_this
tmp_current = &tmp_this->next;
tmp_lst = tmp_lst->next;
}
}
I am working in c++. I'm attempting to make my own iterator for a templated linked list class (without using the STL), but I seem to have trouble using "friends." I want to OListIterator to have access to the "Node" struct within the list class. If anyone could help it would be greatly appreciated!
OListIterator:
#ifndef pg6ec_OListIterator_h
#define pg6ec_OListIterator_h
#include "OList.h"
template <typename T>
class OListIterator
{
private:
T * value;
T * next;
public:
OListIterator()
{}
void setValue(T & val, T & n)
{
value = &val;
next = &n;
}
int operator*()
{
return *value;
}
bool operator==(OListIterator<T> other)
{
return value == other.value && next == other.next;
}
bool operator!=(OListIterator<T> other)
{
return value != other.value && next != other.next;
}
void operator+=(int x)
{
}
};
#endif
List:
#ifndef pg6OList_OListBlah_h
#define pg6OList_OListBlah_h
#include <stdio.h>
#include <stdlib.h>
#include "OListIterator.h"
template <typename T>
class list
{
private:
typedef struct node
{
T value;
struct node * next;
}Node;
Node * root;
public:
list()
{
root = NULL;
}
list(const list & other)
{
Node * temp = other.returnRoot();
Node * currSpot = NULL;
root = new Node;
root->value = temp->value;
currSpot = root;
temp = temp->next;
while (temp)
{
currSpot->next = new Node;
currSpot = currSpot->next;
currSpot->value = temp->value;
temp = temp->next;
}
}
~list()
{
clear();
};
void clear()
{
Node * delNode = root;
while (delNode)
{
root = root->next;
delete delNode;
delNode = root;
}
delete root;
};
Node * returnRoot() const
{
return this->root;
}
int size()
{
int ans = 0;
if (root == NULL)
{
return ans;
}
Node * top = root;
while (top)
{
ans++;
top = top->next;
}
return ans;
}
bool insert(T & item)
{
if (root == NULL)
{
root = new Node;
root->value = item;
return true;
}
else
{
Node * curr = root;
Node * prev = NULL;
while (curr)
{
if ( curr->value > item )
{
Node * insertion = new Node;
insertion->value = item;
if (prev)
{
insertion->next = curr;
prev->next = insertion;
}
else
{
root = insertion;
root->next = curr;
}
return true;
}
else if ( curr->value == item )
{
Node * insertion = new Node;
insertion->value = item;
insertion->next = curr->next;
curr->next = insertion;
return true;
}
prev = curr;
if (curr->next)
{
curr = curr->next;
}
else if ( curr->next == NULL )
{
curr->next = new Node;
curr->next->next = NULL;
curr->next->value = item;
return true;
}
}
}
return false;
}
T get(int x)
{
T ans = root->value;
if (x > size() || x < 0)
{
return ans;
}
Node * curr = root;
for (int i = 0; i < size(); i++)
{
if (i == x)
{
ans = curr->value;
break;
}
curr = curr->next;
}
return ans;
}
int count(T base)
{
int num = 0;
Node * curr = root;
while (curr)
{
if (curr->value == base)
{
num++;
}
curr = curr->next;
}
return num;
}
bool remove(T base)
{
Node * curr = root;
Node * prev = NULL;
if (root->value == base)
{
delete this->root;
root = root->next;
return true;
}
while (curr)
{
if (curr->value == base)
{
Node * temp = new Node;
if (curr->next)
{
T val = curr->next->value;
temp->value = val;
temp->next = curr->next->next;
}
delete curr;
delete curr->next;
prev->next = temp;
return true;
}
prev = curr;
curr = curr->next;
}
return false;
}
void uniquify()
{
Node * curr = root;
Node * next = root->next;
while (curr)
{
while (next && curr->value == next->value)
{
Node * temp = new Node;
if (next->next)
{
T val = next->next->value;
temp->value = val;
temp->next = next->next->next;
delete next;
delete next->next;
curr->next = temp;
next = curr->next;
}
else
{
delete temp;
delete temp->next;
curr->next = NULL;
delete next;
delete next->next;
break;
}
}
curr = curr->next;
if (curr)
next = curr->next;
}
}
OListIterator<T> begin()
{
OListIterator<T> it;
it.setValue(root->value, root->next->value);
return it;
}
OListIterator<T> end()
{
Node * curr = root;
for (int i = 0; i < size(); i++)
{
curr = curr->next;
}
OListIterator<T> it;
it.setValue(curr->value);
return it;
}
};
#endif
I want to OListIterator to have access to the "Node" struct within the list class.
For this, you need to forward-declare the iterator class:
template<typename T> OListIterator;
template <typename T>
class list
{
friend class OListIterator<T>;
//... the rest
}
Alternatively, you can use a template friend declaration, but then any OListIterator type has access to any list type:
template <typename T>
class list
{
template<typename U> friend class OListIterator;
//... the rest
}
Here is a more verbose but unrelated-to-your-code example:
template<typename T> struct Iterator;
template<typename T>
struct List
{
friend struct Iterator<T>;
List(T i) : somePrivateMember(i) {}
private:
T somePrivateMember;
};
template<typename T>
struct Iterator
{
Iterator(List<T> const& list) {std::cout<<list.somePrivateMember<<std::endl;}
};
int main()
{
List<int> list(1);
Iterator<int> iterator(list);
}
The constructor of the Iterator class prints the private member somePrivateMember, whose value is 1.