Doubly Linked List node's next is private - c++

I'm implementing a doubly linked list and I'm using an object of my own as the data being stored.
Here is my object:
#ifndef PLAY_H_INCLUDED
#define PLAY_H_INCLUDED
#include <string>
class Play
{
private:
int m_quarter;
int m_minutes;
std::string oTeam;
std::string dTeam;
int m_down;
int m_yardToGO;
int m_startLoc;
int playDesc;
std::string wholePlay;
int relevance;
int relCounter;
public:
int getQuarter();
int getMinutes();
std::string getoTeam();
std::string getdTeam();
int getDown();
int getYard();
int getStartLoc();
int getPlayDesc();
std::string getwholePlay();
Play(int quarter, int minutes, std::string offense, std::string defense, int dwn, int ytg, int start, int desc, std::string play, int relevance, int relCounter);
~Play();
Play parse(std::string toParse);
std::string findPlay(std::string playDesc);
};
#endif // PLAY_H_INCLUDED
-
Here is my node:
template<class T>
class node{
friend class Play;
T data;
node *next, *prev;
node(const T& t, node *n = 0, node *p = 0) {data=t; next=n; prev=p;}
};
The exact error I get is:
error: node<Play>* node<Play>::next is private.
I assume I get this problem because Play's information is private and inaccessible to node, and to fix this I tried making node a friend class of Play. When I did that I get errors saying "node is not a template type". The error makes no sense to me so I assume this isn't the way to correct my problem.
Thanks.

Use public: above properties which should be public. If you don't specify anything, everything becomes private.
template<class T>
class node{
public: // ADD THIS
friend class Play;
T data;
node<T> *next, *prev;
node(const T& t, node<T> *n = 0, node<T> *p = 0) { // EDIT
data=t; next=n; prev=p;
}
};
Edit: You always need use <> when using template classes, like I edited in above.

All attributes in a class are private by default. Make it a struct instead or add public: at the beginning.
But I guess that is not the problem. When using node *next, *prev;, use this instead:
typedef typename node<T>* MyType;
MyType *next, *prev;

Related

Defining a struct within a class (doubly linked list) using a template

I have implemented each of the methods for this class but I am struggling with this last error. I was given instructions to define the Node struct within the private section of the class linkedlist. I get errors such as:
"error: Node is not a class template"
and
"error: non-template type 'Node' used as a template"
My code works if I rearrange things and place the Node struct outside of the class altogether, but that is not really the solution I am looking for.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
typedef int element_type;
template<class element_type>
class linkedlist
{
private:
struct Node<element_type>{
Node<element_type>* next;
Node<element_type>* prev;
element_type data;
};
Node<element_type>* head;
Node<element_type>* tail;
unsigned int size;
public:
linkedlist();
~linkedlist();
void push_back(const element_type& z);
void push_front(const element_type& z); //add front
void print() const;
// will initialize list with n nodes
explicit linkedlist(unsigned int n);
};
The TL;DR version is to drop the template syntax on Node:
struct Node{
Node* next;
Node* prev;
element_type data;
};
Node* head;
Node* tail;
Because Node is defined inside the class template, it can already access the type element_type. The compiler error is just telling you that you can't use template syntax when declaring a structure which is not itself a template.
Just remove template parameter from struct Node.
struct Node {
Node * next;
Node * prev;
element_type data;
};
Node * head;
Node * tail;
unsigned int size;

C++, instantiating a generic Node storing an instance of an object using templates

I am currently attempting to implement a Doubly Linked List for a Data Structures class.
I currently have implemented a generic Node* class and wanted to hold an instance of another class Student(int i, int j) that I have implemented.
This is what i'm attempting to do in my main method:
Student student1 = Student(10,11);
Node<Student()> node1 = Node<Student()> (student1);
This is the error I am receiving.
Everything worked absolutely fine when the Node was holding a primitive data type like an int but i'm unsure how to account for the difference between storing an int and storing a Student object.
I would love any insight or pushes in the right direction.
Thank you.
Here is my implementation of Node.
#ifndef NODE_H
#define NODE_H
template <class T>
class Node
{
public:
Node();
Node(T k);
virtual~Node();
T key;
Node<T>* prev;
Node<T>* next;
};
#endif
//default constructor
template <class T>
Node<T>::Node()
{
prev = NULL;
next = NULL;
}
template <class T>
Node<T>::Node(T k)
{
prev = NULL;
next = NULL;
key = k;
}
template<class T>
Node<T>::~Node()
{
//implement
}
Student.cpp
#include "Student.h"
Student::Student()
{
mArrivalTime = 0;
mTimeNeeded = 0;
}
Student::Student(int arrivalTime, int timeNeeded)
{
mArrivalTime = arrivalTime;
mTimeNeeded = timeNeeded;
}
Student::~Student()
{
//implement
}
int Student::getArrivalTime()
{
return mArrivalTime;
}
int Student::getTimeNeeded()
{
return mTimeNeeded;
}
Student.h
#ifndef STUDENT_H
#define STUDENT_H
using namespace std;
class Student
{
private:
int mArrivalTime;
int mTimeNeeded;
public:
Student();
Student(int arrivalTime, int timeNeeded);
~Student();
int getArrivalTime();
int getTimeNeeded();
};
#endif
Don't use (), just use the class name. e.g:
Node<Student> node1 = Node<Student> (student1);

Same function for different classes being include in main C++

As you may have noticed from the title I have diverse classes specifically 3 and each one respond to a different tree implementation.
In Tree1.h
class Tree1 {
public:
struct node{
char label;
node* nHMI_ptr;
node* nHD_ptr;
};
node* root;
Tree1();
~Tree1();
bool Empty();
Tree1::node& Root();
void AddSon(int i, node &n, char l);
/*
*
* (other functions)
*/
}
In Tree2.h
class Tree2 {
public:
struct node{
char label;
node* nHMI_ptr;
node* nHD_ptr;
node* nFather_ptr;
node* nHI_ptr;
};
node* root;
Tree2();
~Tree2();
bool Empty();
Tree2::node& Root();
void AddSon(int i, node &n, char l);
/*
*
* (other functions)
*/
}
In Tree3.h
class Tree3{
public:
Tree3();
~Tree3();
struct node;
struct nodeSon{
struct node* node_ptr;
nodeSon* nextNodeSon_ptr;
};
struct node{
char label;
node* nextNode_ptr;
struct nodeSon* nSon;
};
node* root;
bool Empty();
Tree3::node& Root();
void AddSon(int i, node &n, char l);
/*
*
* (other functions)
*/
}
As you can see they have functions and members under the same name or identifier. This is because I want to make various more complex algorithms using this functions but the tricky part is that I want to make this algortihms independent of the class being used. The first thing that came to my mind was to create this algorithms on my main.cpp.
In main.cpp
#include <cstdlib>
#include <iostream>
#include "Tree1.h"
//#include "Tree2.h"
//#include "Tree3.h"
void someFunc(node n) {
//do something by calling Tree functions
//E.g. call Empty(), call AddSon(...)
}
int main(int argc, char** argv) {
return 0;
}
What I am trying to achive is that someFunc(...) works on all of the trees without changing any of the underlying code and just by enabiling one of the #include and disabling the other two.
Is it possible to do it?
How can I accomplish this?
Is it possible to do it?
Yes
How can I accomplish this?
You simply can provide a template function:
template<class TreeType>
void someFunc(TreeType& treeContext, typename TreeType::node& n) {
//do something by calling Tree functions
//E.g. call Empty(), call AddSon(...)
}

Using a get function to access data stored in a node

I have implemented my own doubly linked list, which has templated nodes. Through this node I have stored my own object (Play) which has get gunctions, and I have created an iterator for my list.
for(DLL<Play>::iterator itr=PlayList.begin(); itr!=PlayList.end(); itr++)
if(offense==*how do I access this*getoTeam()){
Here is my node and iterator code:
template<class T>
class node{
public:
T data;
node *next, *prev;
node(const T& t, node<T> *n = 0, node<T> *p = 0) {data=t; next=n; prev=p;}
node() {next = prev = 0;}
};
template<typename T>
class Iterator{
public:
Iterator(node<T> *np=0) : nodePtr(np) {}
T& operator*() const {return nodePtr->data;}
Iterator<T> &operator++(){
nodePtr = nodePtr->next;
return *this;
}
Iterator<T> operator++(int){
Iterator<T> Temp(nodePtr);
nodePtr = nodePtr->next;
return Temp;
}
bool operator==(Iterator<T> i) { return nodePtr == i.nodePtr; }
bool operator!=(Iterator<T> i) { return nodePtr != i.nodePtr; }
private:
node<T> * nodePtr;
};
I'm at a loss for what I would put inside how do I access this. If you could explain why as well, I'd appreciate it.
Thanks.
And just incase, here is my Play object:
#ifndef PLAY_H_INCLUDED
#define PLAY_H_INCLUDED
#include <string>
class Play
{
private:
int m_quarter;
int m_minutes;
std::string oTeam;
std::string dTeam;
int m_down;
int m_yardToGO;
int m_startLoc;
int playDesc;
std::string wholePlay;
public:
int getQuarter();
int getMinutes();
std::string getoTeam();
std::string getdTeam();
int getDown();
int getYard();
int getStartLoc();
int getPlayDesc();
std::string getwholePlay();
Play(int quarter, int minutes, std::string offense, std::string defense, int dwn, int ytg, int start, int desc, std::string play);
~Play();
Play parse(std::string toParse);
std::string findPlay(std::string playDesc);
};
#endif // PLAY_H_INCLUDED
Assuming itr is of type Iterator<Play>, use offense == (*itr).getoTeam().
*itr calls Iterator<Play>::operator*() returning a Play& on which you can then call getoTeam(). For consistency, you should also implement
T* Iterator::operator->() {return &nodePtr->data;}
This way, you could use the more familiar notation offense == itr->getoTeam()

Node implementation Binary Tree

I have the following implementation for the node class:
template<class T> class binTree; // forward declaration
template<class T> class Node {
friend class binTree<T>; // class binTree is friend
public:
//default constructor
Node(const T& d = T(), Node<T> *l = NULL, Node<T> *r = NULL) : data(d),
left(l), right(r) {};
private:
T data;
Node<T> *left, *right;
};
I'm trying to define a new node a the root of my tree, but I keep getting compilation errors...
template<class T>
void binTree<T>::insert(Node<T>*& n, const T& d){
if(n == NULL)
root = Node<T>(d);
}
I'm confused by the const T& d = T() parameter.
I think you just need to declare the binTree class and its members before you try to define the member. The following code compiles for me:
#include <cstdlib>
template<class T> class binTree; // forward declaration
template<class T> class Node {
friend class binTree<T>; // class binTree is friend
public:
//default constructor
Node(const T& d = T(), Node<T> *l = NULL, Node<T> *r = NULL) : data(d),
left(l), right(r) {};
private:
T data;
Node<T> *left, *right;
};
template <class T> class binTree
{
public:
binTree() { }
void insert(Node<T>*& n, const T& d);
private:
Node<T> root;
};
template<class T>
void binTree<T>::insert(Node<T>*& n, const T& d){
if(n == NULL)
root = Node<T>(d);
}
int main(int argc, char **argv)
{
Node<int>* nt;
binTree<int> btree;
btree.insert(nt, 4);
}
Having said this, your concept of the data structure seems messed up. Why does the insert routine in binTree require a node argument?
I'm not quite sure why you have that default override for the d variable in your default constructor. In my implementation of a Node for my Tree class, I had no default assignment. I think the issue is T(). I would recommend not trying to do that default assignment in the params listing, but instead do it in the BMI List. So it would look kind of like "data(new T), left(NULL), right(NULL)"
Additionally I would say I'm not quite certain as to why you are using T(). If that doesn't work, please post the error code so that we can have a better understanding of what is going on.