C++ class pointer I.e node* - c++

In c++ liked list Why we have to write node pointer like node* without specifying int, double etc. and we can also declare new node pointers in main without using any node class declaration.
class Node {
public:
int data;
Node* next;
};
If its any different kind of pointer then what it is called?

In your code
class Node {
public:
int data;
Node* next;
};
there is only one kind of node, and it has an int for data. That is why you don't need to write Node<int> or Node<double>. But you could change your code
template <typename T>
class Node {
public:
T data;
Node<T>* next;
};
This is called a template, and instead of only having an int for the data you can have any type. But now you have to say what that type is when you declare a variable. E.g.
Node<double>* ptr = new Node<double>();

Related

Class inheritance issue

I am trying to implement an AVL tree. Initially I implemented two classes, node and node_AVL as such:
class node{
protected:
int info;
node *l, *r;
public:
node *getRight();
};
class node_AVL : public node{
protected:
int height;
public:
void setHeight(int):
};
The problem arises when for example I try to access the child of a node:
node_AVL *node1 = node2.getRight();
Or
node_AVL node;
node.getRight().setHeight(1);
I get these errors:
Invalid conversion from node* to node_AVL*
Class node has no member setHeight()
How can I solve this?
As the error messages say, this line:
node_AVL *node1 = node2.getRight();
doesn't work because getRight() returns a node*. You could fix this by making node1 a node*, like this:
node *node1 = node2.getRight();
For the second part, you would need to do something like:
node node;
node.getRight()->setHeight(1);
This wouldn't work either since setHeight is a member of node_AVL.
You should maybe redesign your class, bearing in mind what you're trying to accomplish.

Alternative to template variables?

I'm building a binary search tree. As the generic person I am, I want to allow all types to be able to act as keys to nodes in the tree.
So I came up with the following:
class foo
{
private:
template<class T>
struct node
{
T key;
node* left;
node* right;
};
node<>* _root; //point of interest
public:
//.....
template<class T>
void insert(const T& key);
};
As I insert the nodes into the tree, I can create node objects according to the type of the key, but I don't know how to declare the _root in such a way (when using insert on an empty tree, I can easily pick the type for _root).
I believe C++14's template variables can help me here, but unfortunately MSVC's compiler hasn't implemented that feature yet.
Question: How do I declate _root in the most generic way? How did people do it in the past?
Just storing nodes is not a problem:
class foo
{
struct node
{
virtual ~node() {}
node * left;
node * right;
}
template<typename T>
struct key_node: node
{
T key;
~value_node() {}
}
node *root;
};
The problem will come when you want to access the key value within a node (because you will need to store the type information somehow).
Alternately, you can use boost::any instead of a T template:
class foo
{
struct node
{
boost::any key;
node * left;
node * right;
}
node *root;
};
... and use the interface of boost::any to get the value of they key (but even here you will probably need information on the type stored in any before you can access it in a generic way).

Have I to call delete in this destructors?

Have I to call delete in this classes' destructors?
2 pointers to Node:
class Node {
private:
char Ch;
int Key;
Node* L;
Node* R;
public:
Node() { L = NULL; R = NULL; }
Node(char, int, Node*, Node*);
~Node();
};
Vector of pointers to Node:
class Example {
private:
vector<Node*> A;
public:
Node() {}
Node(vector<Node*>);
~Node();
};
In another class of my project I allocate Nodes through "new"!
If you allocate the nodes using new then you will eventually need to delete them, e.g. vector does not delete them for you, it only clears up the vector itself but not what the elements point to (since you have a vector of pointers). As you can tell the ownership of a node can be a bit tricky to establish in your classes - what class should delete? That is why using smart pointers like shared_ptr<> and unique_ptr<> make your life much easier.
e.g.
std::shared_ptr<Node> L;
std::shared_ptr<Node> R;
and
std::vector<std::shared_ptr<Node>> A;
then you do not need to worry about deleting

Structure or class which is better for linked list?

For the implementation of linked list which is better
Using structure
#include <iostream>
using namespace std;
struct Node {
int data;
Node* next;
};
Using class
class ListNodeClass
{
private:
ItemType Info;
ListNodeClass * Next;
public:
ListNodeClass(const ItemType & Item, ListNodeClass * NextPtr = NULL):
Info(Item), Next(NextPtr)
{
};
void GetInfo(ItemType & TheInfo) const;
friend class ListClass;
};
typedef ListNodeClass * ListNodePtr;
Or is their any better way for doing linked list in C++ ?
The only one thing which class and struct makes differ in C++ is the default interface. if you write:
struct MyStruct
{
int a;
}
and:
class MyClass
{
int a;
}
the only one difference is a field in both them. In MyStruct field a is public and in MyClass field a is private. Of course you can manipulate them using public and private keywords in structs and classes both.
If you are programming in C++ you should use classes.
A linked list is one thing, its nodes are another thing. The nodes are part of the implementation of the list. They should not be visible in the interface of a list so their form doesn't really matter. I would do this
class List
{
private:
struct Node
{
int data;
Node* next;
};
public:
...
};

Null Object Pattern, Recursive Class, and Forward Declarations

I'm interested in doing something like the following to adhere to a Null Object design pattern and to avoid prolific NULL tests:
class Node;
Node* NullNode;
class Node {
public:
Node(Node *l=NullNode, Node *r=NullNode) : left(l), right(r) {};
private:
Node *left, *right;
};
NullNode = new Node();
Of course, as written, NullNode has different memory locations before and after the Node class declaration. You could do this without the forward declaration, if you didn't want to have default arguments (i.e., remove Node *r=NullNode).
Another option would use some inheritence: make a parent class (Node) with two children (NullNode and FullNode). Then the node example above would be the code for FullNode and the NullNode in the code above would be of type NullNode inheriting from Node. I hate solving simple problems by appeals to inheritence.
So, the question is: how do you apply Null Object patterns to recursive data structures (classes) with default arguments (which are instances of that same class!) in C++?
Use extern:
extern Node* NullNode;
...
Node* NullNode = new Node();
Better yet, make it a static member:
class Node {
public:
static Node* Null;
Node(Node *l=Null, Node *r=Null) : left(l), right(r) {};
private:
Node *left, *right;
};
Node* Node::Null = new Node();
That said, in both existing code, and amendments above, you leak an instance of Node. You could use auto_ptr, but that would be dangerous because of uncertain order of destruction of globals and statics (a destructor of some global may need Node::Null, and it may or may not be already gone by then).
I've actually implemented a recursive tree (for JSON, etc.) doing something like this. Basically, your base class becomes the "NULL" implementation, and its interface is the union of all interfaces for the derived. You then have derived classes that implement the pieces- "DataNode" implements data getters and setters, etc.
That way, you can program to the base class interface and save yourself A LOT of pain. You set up the base implementation to do all the boilerplate logic for you, e.g.
class Node {
public:
Node() {}
virtual ~Node() {}
virtual string OutputAsINI() const { return ""; }
};
class DataNode {
private:
string myName;
string myData;
public:
DataNode(const string& name, const string& val);
~DataNode() {}
string OutputAsINI() const { string out = myName + " = " + myData; return out; }
};
This way I don't have to test anything- I just blindly call "OutputAsINI()". Similar logic for your whole interface will make most of the null tests go away.
Invert the hierarchy. Put the null node at the base:
class Node {
public:
Node() {}
virtual void visit() const {}
};
Then specialize as needed:
template<typename T>
class DataNode : public Node {
public:
DataNode(T x, const Node* l=&Null, const Node* r=&Null)
: left(l), right(r), data(x) {}
virtual void visit() const {
left->visit();
std::cout << data << std::endl;
right->visit();
}
private:
const Node *left, *right;
T data;
static const Node Null;
};
template<typename T>
const Node DataNode<T>::Null = Node();
Sample usage:
int main()
{
DataNode<char> a('A', new DataNode<char>('B'),
new DataNode<char>('C'));
a.visit();
return 0;
}
Output:
$ ./node
B
A
C