class LinkedList : public IDataList {
public :
Node *head;
Node* lastNode;
int _size = 0;
public : LinkedList() {
this->head = nullptr;
this->lastNode = nullptr;
}
void deAppend(int data) override;
};
Then I have a circular linkedList which is the subclass of LinkedList
class CircularLinkedList : public LinkedList {
public :
Node *head;
Node* lastNode;
int _size = 0;
public : CircularLinkedList() {
this->head = nullptr;
this->lastNode = nullptr;
}
void deAppend(int data) override;
};
This is the method deAppend which adds to the front of the list
void LinkedList::deAppend(int data){
if (this->head== nullptr){
Node *newNode = new Node(data, nullptr);
this->head = newNode;
this->lastNode = newNode;
}else{
Node *newNode = new Node(data, this->head);
this->head = newNode;
}
this->_size+=1;
}
This is my CiruclarLinkedList calling deAppend method
void CircularLinkedList::deAppend(int data) {
LinkedList::deAppend(data);
this->lastNode->next = this->head;
}
The fact is why doesn't the lastNode and the head of CircularLinkedList variables change even though I am calling the method LinkedList::deAppend(data) and changing them in there. IDataList is just an interface.
class IDataList {
public:
virtual void deAppend(int data) = 0;
};
Picture of Variables assignments after the method is called
I think you are declaring your variables twice. I mean inside your base class you declare:
public:
Node *head;
Node* lastNode;
int _size = 0;
When a class inherits from another class publicly, all the public variables of the base class are also declared in the sub class. Which means you already had these variables in your CircularLinkedList class but you declared them again. Now you have two of them and you're changing the ones from your base class. remove the declaration from CircularLinkedList.
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.
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?
I have
class A{
}
class B : virtual public A{
extra property 1
}
class C : virtual public A{
extra property 2
}
class D : virtual public A{
}
class E : virtual public B, virtual public C, virtual public D{
extra property 3
}
And here's my linked list's insert function:
template <typename T>
class LinkedList {
Node<T> *start;
Node<T> *current;
public:
void insert (T newElement)
{
if ( isEmpty() )
{
insertToStart(newElement);
}
else
{
Node<T> *newNode = new Node<T>;
newNode->info = newElement;
newNode->next = NULL;
current = start;
while (current->next != NULL)
{
current = current->next;
}
current->next = newNode;
}
}
Now I would like to create a single linked list that will store all instances of B, C and D without losing the additional attribute of each child class. How can I achieve this using pointer?
I've tried the solution provided here, but it gives me this error: taking address of temporary [-fpermissive].
Linkedlist<A*> list;
B b;
list.insert(&b);
The following piece of code compiles fine with gcc 4.8:
#include <list>
class A
{
};
class B : virtual public A
{
};
int main()
{
std::list<A*> l;
B* b = new B();
l.push_back(b);
B bb;
l.push_back(&bb);
return 0;
}
say in a header file can I have a helper class fully defined and use it in the class file that includes the header. what is the correct way of doing it?
//HEader
class LinkedList() {
public:
LinkedList(int a);
private:
Node *root;
class Node {
int data;
Node *next;
};
};
//cpp file
#include "LinkedList"
LinkedList::LinkedList(int a) {
root = new Node();
root.data = a;
root->next = NULL;
}
when i try doing something like that it ends up saying Node is not a name of type in my header file.
That is totally fine. I made some fixes to your code.
LinkedList.h
class LinkedList
{
public:
LinkedList(int a);
private:
class Node {
public:
int data;
Node *next;
};
Node *root;
};
LinkedList.cpp
LinkedList::LinkedList(int a) {
root = new Node();
root->data = a;
root->next = NULL;
}
You tried to use Node before you even declared and defined it. Default access level in C++ classes is private, so you could not access private data members of Node in LinkedList constructor.
I want to create a class of LinkedList and I have to put the class of Node inside of the class of LinkedList, how do you prefer me to do it?
I think something like:
Class LinkedList {
private:
class Node* head;
public:
class Node {
private:
int data;
Node* next;
Node* prev;
};
};
but I think this is not good.
I would do it like this
class LinkedList {
private:
struct Node {
int data;
Node* next;
Node* prev;
};
Node* head;
public:
...
};
No need for anything in Node to be private since it's not useable outside of LinkedList.