I have some troubles with a c++ project i started. I am trying to implement basic linked list and my attempt includes proxy class in the list class for representing single node. One of the list constructors can get single parameter and initialize the first node of the list with it, but i can't pass that parameter to the proxy class' constructor. Any suggestions how to do it?
Here is some c++ code
template <class TYPE>
class list{
private:
//Proxy class for node representation
class node{
private:
node* next;
TYPE data;
public:
explicit node() : next(nullptr) {}
node (const TYPE& init) : data(init) {}
inline node*& get_next(){
return next;
}
inline TYPE& get_data(){
return data;
}
};
node* head;
unsigned int size;
public:
explicit list() : head(nullptr), size(0) {}
list(const TYPE& init) : list::node(init) {}
Well, you should refer to the instance of node rather than to the class itself. Also, keep in mind that head is a pointer in your example.
Try something like this:
list(const TYPE &init) : head(new node(init)) {}
Related
I'm making an abstract Linked List in C++
Which have a node like this:
template <typename T>
class LL{
protected:
enum {MAX = 512};
class Node{
protected:
Node* next;
Node* prev;
public:
const T& data;
Node(){}
...
};
...
};
Now I want to make a Singly linked list from this abstract class that should only get the next pointer and a Doubly linked list that gets both
How can I achieve this?
I tried making Node:
class Node{
protected:
Node* next;
public:
const T& data;
Node(){}
...
};
Then inside doubly Linked list made a BiNode that inherits from Node and have a prev pointer but that makes a new class and invalidates all the functions that return Node
class ListNode;
class LinkedList {
private:
ListNode* start;
class ListNode {
private:
int data;
ListNode* next;
public:
ListNode() : data(-1), next(NULL) {}
ListNode(int data, ListNode* next=NULL) : data(data), next(next) {}
};
public:
LinkedList() : start(NULL) {}
LinkedList(int data) : start(new ListNode(data)) {}
};
there is a error in LinkedList(int data) : start(new ListNode(data)) {}.
It says "you cannot innitialize LinkedList* value using LinkedList::ListNode construction".
Whats is the exact problem means and solutions???
The forward declaration of class ListNode; is not the same thing as class LinkedList::ListNode defined later.
When the compiler finds ListNode* start;, LinkedList::ListNode is unknown, so the compiler uses the ListNode forward declaration. By the time the compiler gets to start(new ListNode(data)), LinkedList::ListNode is known and has a closer scope so it is used instead of ListNode.
Result: start, a ListNode * is pointed at a LinkedList::ListNode. The types clash and the compiler rejects the code.
The simplest solution is to remove the forward declaration of ListNode, since it's likely just an attempt a to fix an earlier undeclared identifier error and will never be defined, and move ListNode* start; to after the definition of LinkedList::ListNode so that there is no ambiguity.
You cannot forward declare an inner class outside the containing class. So, try declaring it first, and then declaring a pointer to it:
class LinkedList {
private:
class ListNode {
private:
int data;
ListNode* next;
public:
ListNode() : data(-1), next(NULL) {}
ListNode(int data, ListNode* next=NULL) : data(data), next(next) {}
};
ListNode* start;
public:
LinkedList() : start(NULL) {}
LinkedList(int data) : start(new ListNode(data)) {}
};
So I'm trying to work out how inheritance works when templates are in the mix. Most compilers really don't seem to have this figured out yet, so I'm having a little syntax difficulty. All the weird includes in SkipNode.h are from trying to get eclipse to stop yelling at me. I'm getting a syntax error when trying to declare the constructor in SkipNode.h, so any help here would be useful.
Here is node.h
#ifndef NODE_H_
#define NODE_H_
template<class T>
class Node
{
public:
Node(Node<T>* next, Node<T>* prev, T item);
virtual ~Node();
Node* getPrev() { return prev;};
Node* getNext() { return next;};
Node* getItem() { return item;};
void setItem(T item){Node<T>::item = item;};
void setNext(Node* next){Node<T>::next = next;};
void setPrev(Node* prev){Node<T>::prev = prev;};
private:
Node* next;
Node* prev;
T item;
};
Here is SkipNode.h, where skipnode inherits from Node.
#include "Node.h"
#include "Node.cpp"
#include "SkipNode.h"
#include "SkipNode.cpp"
template <class T>
class SkipNode: public Node
{
public:
SkipNode(Node<T>* next, Node<T>* prev, Node<T>* child, T item) : Node(next, prev, item);
virtual ~SkipNode();
Node* getChild(){return child;};
void setChild(Node* child){SkipNode::child = child;};
private:
Node *child;
};
#endif /* SKIPNODE_H_ */
Node is a template, you should pass in template parameter
template <class T>
class SkipNode: public Node<T>
// ^^^
Also you need to provide SkipNode constructor definition as you have provided member iniatilizer list.
update:
SkipNode(Node<T>* next, Node<T>* prev, Node<T>* child, T item)
: Node(next, prev, item);
To:
SkipNode(Node<T>* next, Node<T>* prev, Node<T>* child, T item)
: Node(next, prev, item)
{
}
You're missing an #endif in node.h and you need to provide the template parameter to your base class:
template <class T>
class SkipNode : public Node< T >
....
This level of indirection exists to allow inheritance from a template class by a class that has different (or zero) template parameters. For instance:
class Foo : public Node< int >
What is the current syntax for writing a template member class parameter inside a template class.
This is what I been trying to do:
template <class T>
class Node
{
public:
Node(); // constructor
Node(const Node<T> &); // copy constructor
~Node(); // destructor
T value;
Node *next;
};
template <class T>
class Linked_list
{
public:
Linked_list(); // constructor
Linked_list(const Linked_list<T> &); // copy constructor
~Linked_list(); // destructor
T pop();
void push(T value);
T top();
bool is_empty();
void clear();
private:
Node<T> *head; // COMPILER ERROR
};
Why this is a compiler error?
Node<T> *head; // COMPILER ERROR
Perhaps when you call:
Node<T> *head;
T is not an object type, and it doesn't know how to construct that. Try:
Node<std::string> *head;
or something like that. T is not an object type, it is just like a variable name, except it is actually a variable type within the class Node and LinkedList.
I have a tree_node class and a tree class.
template<typename T>
class tree_node
{
public:
tree_node(const std::string& key_, const T& value_)
: key(key_), value(value_)
{
}
private:
T value;
std::string key;
};
template<typename T>
class tree
{
public:
tree() : root(new tree_node<T>("", ???)) { }
private:
tree_node<T>* root;
};
tree_node expects an instance of T when creating. How can I pass it in the ??? place? I can say T(), but it will work only if T has a parameterless constructor. I can't have a parameterless constructor for tree_node as it won't compile if T doesn't have a parameterless constructor.
I am looking for a way to design tree_node which can hold all types correctly including pointer types.
Edit
After trying various methods, I found that boost::optional is helpful in this case. I can make the T value into boost::optional<T> value. This will solve the empty constructor issue. So I can have another constructor overload of tree_node which just takes a key. This can be used by the root node. Is this the correct way to go?
Thanks..
Init root value should be zero. If you push new node you obviously know value.
template<typename T>
class tree
{
public:
tree() : root(0) { }
void push (const std::string& key, const T & t) {
if (root == 0) {
root = new tree_node<T>(key, t);
} else {
// Make complex tree
}
}
private:
tree_node<T>* root;
};
Add
If you use suffix tree you should make two types of vertices:
enum NodeType { EMPTY_NODE, VALUE_NODE };
class base_tree_node
{
public:
base_tree_node() :parent(0), left(0), right(0) {}
virtual NodeType gettype() = 0;
protected:
base_tree_node* parent;
base_tree_node* left;
base_tree_node* right;
};
class empty_tree_node : base_tree_node
{
virtual NodeType gettype() { return EMPTY_NODE; }
}
template<typename T>
class tree_node : base_tree_node
{
public:
tree_node(const std::string& key_, const T& value_)
: key(key_), value(value_)
{
}
virtual NodeType gettype() { return VALUE_NODE; }
private:
T value;
std::string key;
};
tree( const T & t ) : root(new tree_node<T>("", t )) { }
I have once done a linked list (just for fun) which needed a sentinel node not meant to hold any data, and I had the following structure:
struct BaseNode
{
BaseNode* next;
BaseNode(BaseNode* next): next(next) {}
};
template <class T>
struct Node: public BaseNode
{
T data;
Node(const T& data, BaseNode* next): BaseNode(next), data(data) {}
};
template <class T>
struct List
{
BaseNode* head;
List(): head(new BaseNode(0)) {}
void add(const T& value)
{
Node<T>* new_node = new Node<T>(value, head->next);
head->next = new_node;
}
T& get_first()
{
assert(head->next);
return static_cast<Node<T>*>(head->next)->data;
}
//...
};
The class itself must make sure it gets necessary casts right and doesn't try to cast head or root itself to Node<T>.
A tree node should have (or be) a collection of child nodes. A tree should have (or be) a collection of root nodes. Both those collections should be the same type. Very simply:
template <class T>
class NodeCollection
{
std::vector<Node<T> *> nodes;
public:
// any operations on collection of nodes
// copy ctor and destructor a must!
};
template <class T>
class Node : public NodeCollection<T>
{
T value;
public:
// ctor
// access to value
};
template <class T>
class Tree : public NodeCollection<T>
{
public:
// ctor
};
This way the shared definition of Tree and Node is actually in NodeCollection, and so Tree doesn't need to carry a dummy value.