I have been implementing the Red Black Trees in C++ using inheritence. I have 4 Classes, Node, Tree, RBNode, RBTree.
class Node
{
protected:
int data;
Node *left;
Node *right;
Node *parent;
public:
Node();
Node(int data);
void print_node(ofstream &file);
Node * find_node(int data);
void insert_node(Tree *t);
void left_rotate_node(Tree *t);
void right_rotate_node(Tree *t);
void delete_node(Tree *t);
}
class Tree
{
protected:
Node * root;
list<int> treedata;
public:
Tree();
virtual Node * get_root();
virtual void set_root(Node *root_node);
void insert_into_tree();
void delete_from_tree();
virtual void print_tree();
}
RBNode and RBTree inherit Node, Tree respectively. But I am not able to use the functions of the Node class. For example, the function void Tree::insert_node(Tree *t);
Even in the class RBNode, this function does the same work except that the funntion receives RBTree as the parameter. How can I make use of the same function without redeclaring it in RBNode. I thought of using casting inside function, but how will I know which classes object is calling the function.
Please give me some suggestions. I am new to C++.
Either the inheritance was not properly defined, or there is a confuson on insert_node(Tree *t) which is defined in the Node and not in the Tree.
Anyway, the following minimal code example compiles well:
class Tree;
class Node
{
protected:
int data;
Node *left,*right, *parent;
public:
Node(int data=0) : data(data), left(nullptr), right(nullptr), parent(nullptr) {}
void insert_node(Tree *t) { cout << "Insert" << endl; }
};
class Tree
{
protected:
Node * root;
list<int> treedata;
public:
Tree() : root(nullptr) {}
};
class RBSnode : public Node {}; // public inheritance
class RBStree : public Tree {};
...
RBSnode n;
RBStree t;
n.insert_node(&t);
Note that in absence of the public inheritance specifier, private inheritance is assumed: within the class you have acces to all the protected and public members of the base class, but outside, the class, you don't see the inherited members. I guess it's what happenned to you.
Related
So i'm trying to implement a binary search tree and avl tree. Each of these classes using different but similar types of nodes. The classes for nodes look like this:
class node
{
protected:
int key;
node* parent, * left, * right;
public:
node(int key, node* parent = nullptr) :key(key), parent(parent), left(nullptr), right(nullptr) {}
~node() {}
};
class avl_node : public node
{
private:
int height;
public:
avl_node(int key, int height, avl_node* parent = nullptr) :node(key, parent), height(height) {}
~avl_node() {}
};
This mostly works. Any node can have connexions with any other node, and any avl_node with any other avl_node. The issue that I think of is that a node could technically have a parent or children avl_node because of polymorphism, and I wouldn't want that to happen. Although I can avoid that by being careful, i wouldn't want it to be possible at all. Is there a way?
p.s. I want to keep the classes related
If it's enough, you could explicitly delete the version of constructor that would take an avl_node*
class node
{
protected:
int key;
node* parent, * left, * right;
public:
node(int key, node* parent = nullptr) :key(key), parent(parent), left(nullptr), right(nullptr) {}
node(int, avl_node*) = delete;
~node() {}
};
Of course, this solution is not foolproof. If you brought an avl_node hidden behind a node pointer, the compiler wouldn't be able to tell (and since polymorphism is mainly dynamic, you would only be protected in this specific case where you attempt to assign the pointer directly)
This would compile.
avl_node myavl;
node n(0, static_cast<node*>(&myavl));
You could try dynamic-casting in the node constructor to tell if it's an avl_node being passed (your nodes would need a vtable for that), but that would make it impossible to call the constructor like that from the avl_node constructor.
Another option would be making a separate constructor intended specifically for the subclass
class node
{
protected:
int key;
node* parent, * left, * right;
node(int key, avl_node* parent) : key(key), parent(parent), left(nullptr), right(nullptr) {}
public:
node(int key, node* parent = nullptr) :key(key), parent(parent), left(nullptr), right(nullptr) { /* do something to not allow avl_node* to be passed */ }
~node() {}
};
You can get rid of polymorphism and avoid code duplication by using a class template for the base, and members that depend on the template argument.
Example:
template<typename T>
class node
{
protected:
int key;
node* parent, * left, * right; // Note: these are actually 'node<T>'.
public:
node(int key, node* parent = nullptr)
: key(key), parent(parent), left(nullptr), right(nullptr) {}
void set_parent(node* p) { parent = p; }
};
class avl_node : public node<avl_node>
{
private:
int height;
public:
avl_node(int key, int height, avl_node* parent = nullptr)
: node(key, parent), height(height) {}
};
class silly_node : public node<silly_node>
{
public:
silly_node() : node(0) {}
};
int main()
{
// Fine
avl_node an(0, 1);
// Fine
avl_node bn(0, 1, &an);
// Also fine
bn.set_parent(&an);
// Fine
silly_node sn;
// Compilation error
avl_node cn(0, 1, &sn);
// Also compilation error
bn.set_parent(&sn);
}
I am quite a newbie when it comes to design patterns so am having a hard time grasping the concept of the decorator design pattern. Is it possible to decorate a singly linked list class to a doubly linked list class which inherits from it? I would like to decorate the following class:
ListAsSLL.h:
#ifndef LISTASSLL_H
#define LISTASSLL_H
class ListAsSLL
{
protected:
struct node{
int i;
struct node* next;
};
node* head;
node* tail;
int listSize;
public:
ListAsSLL();
virtual void addToBeginning(int obj);
virtual void addAtPos(int obj, int i);
virtual void addToEnd(int obj);
virtual void del(int i);
virtual void overwrite(int obj, int i);
virtual void grow();
virtual void shrink();
};
#endif //LISTASSLL_H
Giving the doubly linked list class the same functionality with the added feature of having a struct with a pointer to the previous node.
Hopefully someone can shed some light on how to do this. Thanks in advance.
Here is an example of how it can be implemented. I added another virtual method createNode and show possible implementation of addToBeginning().
class ListAsSLL
{
protected:
struct node{
int i;
struct node* next;
};
node* head;
node* tail;
int listSize;
virtual node *createNode() { return new node; }
public:
virtual void addToBeginning(int obj)
{
node *node = createNode();
node->i = obj;
node->next = head;
if( !head ) tail = node;
head = node;
++listsize;
}
...
};
class ListAsDLL
{
protected:
struct dnode : node{
node* prev;
};
virtual node *createNode() { return new dnode; }
public:
virtual void addToBeginning(int obj)
{
node *prevHead = head;
ListAsSLL::addToBeginning( obj );
static_cast<dnode *>( head )->prev = prevHead;
}
...
};
Code was not tested, though may have logic errors, as was written to show general idea.
Is it possible to implement linked lists using inheritance? for example:
class List {/* ... */}; // abstract class
class IntList : public List {/* ... */}; // derived class
One possible solution is to make the List base class to only handle nodes, i.e. keep track oh the list head, tail and adding/removing nodes. The List class could have a basic Node class that is inherited by e.g. IntList for the specialization.
Something like
class List
{
public:
virtual ~List() {}
protected:
// Protected constructor so this class can only be inherited
List() {}
struct Node
{
Node* next;
Node* prev;
};
void add_head(Node*);
void add_tail(Node*);
Node* pop_head();
Node* pop_tail();
Node* get_head();
Node* get_tail();
private:
Node* head;
Node* tail;
};
class IntList : public List
{
public:
IntList();
~IntList();
void add_head(int); // Creates an `IntNode` and calls `add_head` with that
void add_tail(int); // Creates an `IntNode` and calls `add_tail` with that
int pop_head(); // Calls `pop_head` to get the node, and downcast to `IntNode`
int pop_tail(); // Calls `pop_tail` to get the node, and downcast to `IntNode`
int get_head(); // Calls `get_head` to get the node, and downcast to `IntNode`
int get_tail(); // Calls `get_tail` to get the node, and downcast to `IntNode`
private:
struct IntNode : List::Node
{
int value;
};
};
I have a linked list program where the TailNode class inherits from the Node class and both classes use a Data class parameter. Data has already been forward declared in my Node class header, but I don't understand why my program runs fine even though I haven't forward declared Data in my TailNode derived class header.
Do derived classes also inherit forward declarations used by the base class? What am I missing here?
Here are my two headers Node and TailNode...
Node.h
#ifndef NODE_H
#define NODE_H
class Data; //forward declaration
class Node
{
public:
Node(){}
virtual ~Node(){}
virtual Node* Insert(Data *theData) = 0;
virtual void Show() = 0;
};
#endif
TailNode.h
#ifndef TAILNODE_H
#define TAILNODE_H
class TailNode : public Node
{
public:
TailNode(){}
~TailNode(){}
virtual Node* Insert(Data *theData);
virtual void Show() { }
};
#endif
//TailNode inherits everything from Node and seems to not need Data forward declared maybe because it was already forward declared for Node class?
Because there is absolutely no connection between class Data and class Node whatsoever, other than they happen to be in the same header file.
Header files are to make sharing declarations easy, but they exist entirely for your convenience. They have no effects whatsoever on the code contained in them. Let me see if I can clarify with an example:
apple.h
class Data;
class Node
{
public:
Node(){}
virtual ~Node(){}
virtual Node* Insert(Data *
banana.h
theData) = 0;
virtual void Show() = 0;
};
class TailNode : public Node
{
public:
TailNode(){}
~TailNode(){}
virtual Node* Insert(Data *theData);
virtual void Show() { }
};
mycode.cpp
#include "apple.h"
#include "banana.h"
int main() {
}
The #include inside mycode.cpp effectively copy-pastes whatever is in that file into mycode.cpp. Since the copy-pasted code is valid:
class Data;
class Node
{
public:
Node(){}
virtual ~Node(){}
virtual Node* Insert(Data *theData) = 0;
virtual void Show() = 0;
};
class TailNode : public Node
{
public:
TailNode(){}
~TailNode(){}
virtual Node* Insert(Data *theData);
virtual void Show() { }
};
int main() {
}
Then the program is valid, and works fine!
I have an abstract class Node which contains a pure virtual method stub matches, requiring another instance of a Node (i.e. instance of something that subclasses Node) as a parameter.
class Node; // forward declaration
class Node {
public:
Node() : parentNode(this) {}
virtual ~Node() {}
Node* parentNode;
virtual bool matches(const Node& node) const = 0;
};
How can I implement matches in a subclass such that the parameter can be of the subclasses type as opposed to Node?
E.g. I want something like the following to register as the implemented version of the contract from Node, so that I can access NodeImpl specific properties as part of the function which I would otherwise be unable to do:
class NodeImpl : public Node {
private:
int foo;
...
};
...
bool NodeImpl::matches(const NodeImpl& n) const {
return this->foo == n.foo;
}
(I did have a try using templates to achieve this sort of effect, but I wasn't sure that I was doing it quite right. I found myself propagating the templates all over my code and encountering a myriad errors as such, and was hoping to get an idea of what the right method for this exactly is before I waste yet more time on what might well be also the wrong way of doing things.)
What I tried was:
template <class T>
class Node;
template <class T>
class Node {
public:
Node() : parentNode(this) {}
virtual ~Node() {}
Node* parentNode;
virtual bool matches(const T& node) const = 0;
};
So that I could call matches generically in a template function like so:
template <class T>
void pathComp(Node<T>& currNode, Node<T>& rootNode) {
Node<T> *node = &currNode;
while (node->matches(rootNode)) {
...
}
}
I couldn't quite get this method to work, plus I didn't like how I seemingly had to have class NodeImpl : public Node<NodeImpl> as my inheritance, something about that didn't seem quite right. Any advice as to whether I was on the right lines or not would be great!
You can't really do that in general, because it wouldn't be type-safe. For example:
struct Node { virtual bool matches(const Node &) const = 0; }
struct NodeA : Node { virtual bool matches(const NodeA &) const; };
struct NodeB : Node { virtual bool matches(const NodeB &) const; };
NodeA a; // compiler doesn't allow, but if it did...
NodeB b;
Node &c = a;
c.matches(b); // oops!
The way you are talking about implementing it, there would be an assumption that b was the same type as a, but there is no way for the compiler to verify that assumption in general, so it isn't going to allow it.
However, if you are using two nodes of the same type, you can always have the matches() function just not be virtual:
struct Node { }
struct NodeA : Node { bool matches(const NodeA &) const; };
NodeA a1;
NodeA a2;
a1.matches(a2); // fine
You should honor the superclass' contract signature. Then if you need
to access sub-class properties, just cast to the sub-class, as needed.