Null Object Pattern, Recursive Class, and Forward Declarations - c++

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

Related

Alternative to virtual templated function

I currently use a tree structure, made out of subtypes of the class Node. The base Node class looks something like this:
// Base Node Type
class Node
{
public:
virtual ~Node() = default;
virtual std::vector<Node*> GetChildren() const = 0;
};
Here are some example Node subtypes:
// First Node Subtype
class NodeOne : public Node
{
public:
NodeOne(std::unique_ptr<Node>&& t_node)
: m_Node{ std::move(t_node) }
{
}
virtual ~NodeOne() = default;
std::vector<Node*> GetChildren() const override
{
std::vector<Node*> children{};
AddChildren(children, m_Node);
return children;
}
private:
std::unique_ptr<Node> m_Node{};
};
This node owns a pointer to another child Node (can be null).
// Second Node Subtype
class NodeTwo : public Node
{
public:
NodeTwo(std::unique_ptr<NodeOne>&& t_leftNode, std::unique_ptr<NodeOne>&& t_rightNode)
: m_LeftNode{ std::move(t_leftNode) }, m_RightNode{ std::move(t_rightNode) }
{
}
virtual ~NodeTwo() = default;
std::vector<Node*> GetChildren() const override
{
std::vector<Node*> children{};
AddChildren(children, m_LeftNode);
AddChildren(children, m_RightNode);
return children;
}
private:
std::unique_ptr<NodeOne> m_LeftNode{};
std::unique_ptr<NodeOne> m_RightNode{};
};
This node owns a pointer to two child NodeOnes (both can be null). As you can see, both implement the pure virtual function GetChildren(). This is the implementation of the AddChildren() function (it just adds the Node* and its Node* children to the std::vector<Node*>):
// AddChildren() Implementation
template<typename T>
void AddChildren(std::vector<Node*>& t_vec, const std::unique_ptr<T>& t_child)
{
if (!t_child)
return;
auto children{ t_child->GetChildren() };
t_vec.insert(t_vec.end(), children.begin(), children.end());
t_vec.push_back(t_child.get());
}
I recently noticed, getting children of all Node subtypes from GetChildren() is not what I actually want most of the time. I often need children of just one specific interface or type. I wanted to achieve this by making the GetChildren() function a template<>, and then in AddChildren() I would only add a Node* to the std::vector<Node*> if it is of that type (with a constexpr if statement or something similiar). I just found out that template<> on a virtual function is not allowed in C++. Is there any way I could GetChildren() of only one type (I don't want to use RTTI so I would prefer a compile time solution).

C++ class pointer I.e node*

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>();

Make sure that all constructors call same function c++, design pattern

Let us assume that we have a class called Node which has a member called sequence and id. We want to print the sequence of the Node in many differnt ways. Instead of adding the print functions directly into the Node class, we put them into a seperate class called NodePrinter. Each Node, needs to have a "working" NodePrinter in any case.
Which implies that:
Node has a NodePrinter * printer member
Every constructor of Node needs to create a new NodePrinter
My idea now was to create a BaseNode and move the NodePrinter into that one. It has only one constructor, which takes a Node as an input and assigns it to the NodePrinter:
#include <iostream>
#include <string>
using namespace std;
class NodePrinter;
class Node;
class BaseNode
{
public:
BaseNode() = delete;
BaseNode(Node * node);
~BaseNode();
NodePrinter * printer;
};
class Node: public BaseNode
{
public:
Node(string sequence): BaseNode(this), sequence(sequence){}
Node(int id, string sequence): BaseNode(this), sequence(sequence), id(id){}
int id;
string sequence;
};
class NodePrinter
{
private:
Node * node;
public:
NodePrinter() = delete;
NodePrinter(Node * node): node(node){}
void print_node()
{
std::cout<<node->sequence<<endl;
}
};
BaseNode::BaseNode(Node * node)
{
node->printer = new NodePrinter(node);
}
BaseNode::~BaseNode()
{
delete printer;
printer = nullptr;
}
int main()
{
Node node("abc");
node.printer->print_node();
return 0;
}
Thereby each node is forced to call BaseNode(this) and the resources get allocated.
Is this reasonable, or is this whole approach already twisted from the start? Is there a better way to do this?
One thing that seems odd to me is that the printer depends on an instance of Node, shouldn't it be possible for a single printer to print multiple nodes? And I also wouldn't have Node depend on a NodePrinter either, because then you can't print the same node with multiple printers.
Anyhow, if you really need to keep the 1-to-1 correspondence, the simplest way is to just initialize the NodePrinter directly where the member variable is declared in Node:
#include <iostream>
#include <memory>
#include <string>
class Node;
class NodePrinter
{
private:
Node * node;
public:
NodePrinter() = delete;
NodePrinter(Node * node): node(node){}
void print_node();
};
class Node
{
public:
Node(std::string sequence) : sequence(std::move(sequence)){}
Node(int id, std::string sequence) : id(id), sequence(std::move(sequence)) {}
int id;
std::string sequence;
std::unique_ptr<NodePrinter> printer = std::make_unique<NodePrinter>(this);
};
void NodePrinter::print_node()
{
std::cout<< node->sequence << '\n';
}
int main()
{
Node node("abc");
node.printer->print_node();
return 0;
}
Live demo on wandbox.

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:
...
};

Super vs Subclass inheritance of a constructor C++

So this is the base class for a binary search tree with left, right, parent and data.
template<class Data>
class BSTNode
{
public:
/** Constructor. Initialize a BSTNode with the given Data item,
* no parent, and no children.
*/
BSTNode(const Data & d) : data(d)
{
left = right = parent = 0;
}
BSTNode<Data>* left;
BSTNode<Data>* right;
BSTNode<Data>* parent;
Data const data; // the const Data in this node.
/** Return the successor of this BSTNode in a BST, or 0 if none.
** PRECONDITION: this BSTNode is a node in a BST.
** POSTCONDITION: the BST is unchanged.
** RETURNS: the BSTNode that is the successor of this BSTNode,
** or 0 if there is none.
*/
BSTNode<Data>* successor()
{
BSTNode<Data>* cursor;
BSTNode<Data>* par;
cursor = this->right;
par = this->parent;
if (this->right != NULL)
{
while (cursor->left != NULL) {
cursor = cursor->left;
}
return cursor;
}
if ((this->right == NULL) && (this == par->left))
return this->parent;
if ((this->right == NULL) && (this == par->right))
{
do
{
cursor = par;
par = par->parent;
if (par == NULL)
{return cursor;}
} while(cursor != par->left);
return par;
}
if (this->right == NULL && this->parent == NULL)
return NULL;
return NULL;
}
};
The subclass is RSTNode that is supposed to use all the members of BSTNode and add a priority on top of that:
template<class Data>
class RSTNode: public BSTNode<Data>
{
public:
int priority;
RSTNode(Data const & d)
: BSTNode<Data>(d)
{
//call a random number generator to generate a random priority
priority = rand();
}
};
Now the problem is i'm not sure how to implement the constructor for the RSTNode as it does not recognize the members of BSTNode for some reason. I know that it should recognize them as it is supposed to inherit this information. Any help is appriciated.
Ok, I compiled this in Visual Studio...
template<class Data>
class BSTNode
{
public:
/** Constructor. Initialize a BSTNode with the given Data item,
* no parent, and no children.
*/
BSTNode(const Data & d) : data(d)
{
left = right = parent = 0;
}
BSTNode<Data>* left;
BSTNode<Data>* right;
BSTNode<Data>* parent;
Data const data; // the const Data in this node.
};
template<class Data>
class RSTNode : public BSTNode<Data>
{
public:
int priority;
RSTNode(Data const & d)
: priority(rand()),
BSTNode<Data>(d)
{
left = 0; //Accessible because public
right = 0;
parent = 0;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
RSTNode<std::string> node(std::string("test"));
return 0;
}
It compiled so no access issues. Like other posters above it seems to me that you are either not posting the detail of your problem, or you are not understanding something fundemental.
>Now the problem is i'm not sure how to implement the constructor for the RSTNode as it >does not recognize the members of BSTNode for some reason. I know that it should recognize >them as it is supposed to inherit this information. Any help is appriciated.
The code above implements a constructor, or if you wanted to specifically have left, right and parent set then you would need :
BSTNode(const Data & d, BSTNode* l, BSTNode* r, BSTNode* p)
: data(d),
left(l),
right(r),
parent(p)
{
}
and then use it in the RSTNode, or have a similar one for RSTNode that passed through to that one....
RSTNode(Data const & d, BSTNode* l, BSTNode* r, BSTNode* p)
: priority(rand()),
BSTNode<Data>(d,l,r,p)
{
}
Hope that helps a little, note that you should prefer initialiser lists to direct access to members in the ctor. But if you cannot change the base class then you would need to...
Corrected typo - data -> Data
That's because the default scope for data members is private. You need to declare them as protected if you want to access them in a subclass.
Better still, add a constructor to BSTNode that allows you to pass in initialisation values, and call this from the RSTNode constructor, since it should be the base class that is managing the lifetime of its members.
If I've read this correctly your attempting to inherit from a templated class:
class RSTNode: public BSTNode<Data>
Where your class definition of BSTNode isn't a templated class?
class BSTNode {
Is this part of the problem or have you pasted the wrong code?
You could fix it by either templating BSTNode
template <typename T> class BSTNode {
or deriving RSTNode from non-templated BSTNode:
class RSTNode: public BSTNode
However the fact that you've tried to to what you've written implies you aren't really understanding class definitions at a much deeper level, and the fact you are trying to set base class parameters directly in a derived class constructor and that you've made them public would lead me to believe you need to learn more about object oriented design - so although this might solve your problem technically, it's only tip of the iceberg when it comes to the issues you are having.
Also saying "it does not recognize the members of BSTNode for some reason" isn't very helpful as I suspect that isn't the exact output of your compiler when you try to do it.