How to correctly delete base class elements
base class:
class node
{
private:
node *left, *right, *parent;
public:
node(node* parent,node* left,node* right);
};
subclass:
class nodeFunc: public node
{
private:
int x;
public:
nodeFunc(int x, node* parent, node* left, node* right);
};
class, which contains vector:
class tree
{
private:
vector<node*> nodes;
public:
tree(int size);
~tree();
};
in constructor:
tree::tree(int size)
{
for (int i = 0; i < size; i++)
nodes.push_back( new nodeFunc(i,NULL,NULL,NULL) );
}
destructor:
tree::~tree()
{
for (vector<node*>::iterator it=nodes.begin();it!=nodes.end();++it)
{
delete (*it);
}
nodes.clear();
}
in main.cpp:
int main()
{
tree* myTree = new tree(10);
delete myTree;
cout<<"end"<<endl;
}
I use debugger to see what happened in every line. After first, myTree->nodes contains 10 elements. After delete myTree->nodes contains 58 items.
After the line delete myTree;, the pointer myTree becomes invalid, because it points to deallocated memory. You cannot dereference it.
As for deleting base class objects, you just need to implement a virtual desctructor in the base class: virtual ~node( );.
Related
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.
When i run the destructor i get a run failed and i am not sure why here is my tree header
class ExpressionTree {
private:
ExpressionNode* root;
public:
ExpressionTree() :
hashmap(100000),
root(NULL) {
};
virtual ~ExpressionTree(){
helper(root);
}
void helper(ExpressionNode *node) {
if ( !node ) {
return;
} else {
helper( node->getLeft( ) );
helper( node->getRight( ) );
delete node;
}
}
};
and my node header
class ExpressionNode {
private:
ExpressionNode* left;
ExpressionNode* right;
string data;
public:
virtual ~ExpressionNode(){
delete left;
delete right;
}
};
Now everything works fine if in the ExpressionTree class i only destroy the root but i believe i am leaking memory that way. Is that in fact the right way or is there something wrong with my recursive destruction.
The ExpressionNode destructor adequately cleans up it's memory which because it destroys it's children which adequately clean up their memory and so on. What you are doing right now is double-freeing the nodes; once by helper() and once by the destructors themselves. All you need to do is destroy the root node
virtual ~ExpressionTree(){
delete root;
}
all the children nodes will be deleted through the destructors.
I am building a linked list, where nodes are all linked to Head. The Head is derived from node, but the Head requires a pointer to last node. See the comment at the top of code.
/* Base <= node <= node <= node
* | ^
* | ptr to last node |
* -------------------------
*/
class Node {
private:
Node* prev;
public:
explicit Node(Node* parent) : prev(parent) {
Node* foo_ptr = this;
while (foo_ptr->prev != 0) {
foo_ptr = foo_ptr->prev;
}
// foo_ptr points to Base, how can I now change Base::last?
}
};
class Base : public Node {
private:
Node* last;
public:
Base() : Node(0), last(this) {}
};
How can I change change variable Base::last when adding new node, for example:
Node* n = new Base;
new Node(n); // can Node constructor update n->last?
I was thinking to use virtual function to update the variable, but according to this post: Calling virtual functions inside constructors, its a no no so I do not want to do it. So is there a good way of achieving this type of linked list?
Thanks...
http://coliru.stacked-crooked.com/a/213596aa1ffe7602
I added a flag value so we can tell that we actually accessed the Base class:
#include <iostream>
class Node {
private:
Node* prev;
public:
inline void changeBaseLast(Node* base);
explicit Node(Node* parent) : prev(parent) {
Node* foo_ptr = this;
while (foo_ptr->prev != 0) {
foo_ptr = foo_ptr->prev;
}
// foo_ptr points to Base
// now change Base::last
changeBaseLast(foo_ptr);
}
int data;
};
class Base : public Node {
private:
Node* last;
public:
int flag;
Base() : Node(0), last(this), flag(0) {}
};
//Here, we can see that we change the base_ptr to 1.
void Node::changeBaseLast(Node* base) {
Base* base_ptr = static_cast<Base*>(base);
base_ptr->flag=1;
}
int main() {
Node* n = new Base;
new Node(n);
std::cout << static_cast<Base*>(n)->flag << std::endl;
}
If you pull out the part that refers to the derived class and then inline it, there should be no problems with this. Notice, though, that I need to define the functions that refer to the derived class after I define the derived class.
If you're sure that the last node will always be a Base object, then using static_cast<Base*> may not be that bad.
class Base : public Node {
...
// Factory method to create child nodes
Node* getNode(Node* parent) {
Node* newNode = new Node(parent);
last = newNode;
return newNode;
}
}
This one should be even easier to understand and still uses static_cast, for you want to append by means of the Base class.
class Node {
private:
Node* prev;
public:
explicit Node() : prev{nullptr} { }
void setParent(Node *parent) {
prev = parent;
}
};
class Base : public Node {
private:
Node* last;
public:
Base() : Node{}, last{this} { }
void append(Node *node) {
node->setParent(last);
last = node;
}
};
int main() {
Node* n = new Base;
static_cast<Base*>(n)->append(new Node{});
}
Anyway, I don't understand the need of the Base class.
Can't you simply store somewhere (as an example a struct) two pointers, one for the head of the list and one for the last node?
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 this tree with different types of nodes that I need to do a deep copy on. The hierarchy looks something like this:
class AllNodes
{
//this is a purely virtual base class
};
class TreeNode : public AllNodes
{
AllNodes *rChild, *lChild;
};
class LeefNode : public AllNodes
{
int value;
};
The problem is that when I want to do a deep copy of the entire tree, I don't know what nodes will have children and what nodes will have values. I've tried this, but it wont work (for obvious reasons):
void AllNodes::deepCopy(AllNodes* &copied, AllNodes* o)
{
if(o->rChild == nullptr)
copied->rChild = nullptr;
else
{
copied->rChild = o->rChild;
deepCopy(copied->rchild, o->rChild);
}
if(o->lChild == nullptr)
copied->lChild = nullptr;
else
{
copied->lChild = o->lChild;
deepCopy(copied->lChild, o->lChild);
}
}
Does anyone have some ideas of how to accomplish this?
Create a virtual method and implement it in TreeNode and LeafNode.
class AllNodes
{
//this is a purely virtual base class
virtual AllNodes* copy() const = 0;
};
class TreeNode : public AllNodes
{
AllNodes* rChild, lChild;
virtual AllNodes* copy() const {
TreeNode *n = new TreeNode;
n->rChild = rChild->copy();
n->lChild = lChild->copy();
return n;
}
};
class LeafNode : public AllNodes
{
int value;
virtual AllNodes* copy() const {
LeafNode *n = new LeafNode;
n->value = value;
return n;
}
};
(Just a draft)
This is polymorphic behavior (creating a deep copy, based on the concrete type of the object). As such, it should be implemented in a virtual function, accross the entire nodes hierarchy.
The function to perform the deep copy is usually called clone:
class AllNodes
{
//this is a purely virtual base class
public:
virtual AllNodes* clone() = 0;
};
class TreeNode : public AllNodes
{
AllNodes *rChild, *lChild; // you skipped declaring lChild as a pointer
public:
virtual AllNodes* clone() override // recursive implementation for child nodes
{
return new TreeNode{
rChild ? rChild->clone() : nullptr,
lChild ? lChild->clone() : nullptr }; // assume existence of this
// constructor
}
};
class LeafNode : public AllNodes
{
int value;
public:
virtual AllNodes* clone() override
{
return new LeafNode{ value }; // assume existence of this constructor
}
};
Client code (deep copy of the entire tree):
AllNodes *original; // filled in elsewhere
AllNodes *deepCopy = original->clone();