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.
Related
I've wrote this class, and the member function, and have created the object in the main function. It calls the show function just fine, but the show function itself says that it cannot access root because it is not declared in scope. I set the data members as public, and I didn't think I would need a getter/setter for this. What's the best way to allow show() access to root?
class bst
{
public:
struct Node
{
public:
int data;
struct Node *left;
struct Node *right;
Node* root = NULL;
};
void show();
};
void bst::show()
{
if(root == NULL) return;
show(root->left); //Visit left subtree
printf("%d ",root->data); //Print data
show(root->right); // Visit right subtree
}
It doesn't look like you actually defined an instance of struct Node as a member of your bst class. You defined the nested class, but declared no instances of it. Declare one, and you can use the name it's declared under to make this work, e.g.:
class bst
{
public:
struct Node
{
public:
int data;
struct Node *left;
struct Node *right;
Node* root = NULL;
};
Node node;
void show();
};
void bst::show()
{
if(node.root == NULL) return;
show(node.root->left); //Visit left subtree
printf("%d ",node.root->data); //Print data
show(node.root->right); // Visit right subtree
}
It's possible you meant for root to be a member of bst, in which case you'd rearrange things to put it in bst, not the declaration of the Node class:
class bst
{
public:
struct Node
{
public:
int data;
struct Node *left;
struct Node *right;
};
Node* root = NULL;
void show();
};
in which case you wouldn't need to qualify the references with node. as shown in the first example.
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'm writing a doubly linked list in C++ and have a class Node which I'm using for a singly linked list. Below shows the definition of the class.
Node.h
#ifndef NODE_H
#define NODE_H
template <class T>
class Node {
public:
Node<T>() { next = nullptr; }
Node<T>(T init) { data = init; next = nullptr; }
void setData(T newData) { data = newData; }
void setNext(Node<T> *nextNode) { next = nextNode; }
const T getData() { return data; }
Node<T> *getNext() { return next; }
private:
T data;
Node<T> *next;
};
#endif
Obviously the main difference between a singly linked list and doubly linked list is a pointer to the previous Node, so I'm trying to inherit everything from the Node class in a new class and simply add a prev attribute:
DoublyLinkedList.h
#ifndef DOUBLY_LINKEDLIST_H
#define DOUBLY_LINKEDLIST_H
#include "Node.h"
template <class T>
class DLLNode : public Node {
public:
// Inherit default constructor from Node and set prev to nullptr;
DLLNode<T>() : Node<T>(), prev() {}
// Inherit constructor from Node and set prev to nullptr;
DLLNode<T>(T init) : Node<T>(init), prev() {}
Node<T> *getPrev() { return prev; }
private:
Node<T> *prev;
};
/*
TODO: Implement doubly linked list class
*/
#endif
My driver is, simply, the following:
driver.cc
#include <iostream>
#include "DoublyLinkedList.h"
int main()
{
DLLNode<int> test;
return 0;
}
When I compile, I get the following errors:
./DoublyLinkedList.h:7:24: error: expected class name
class DLLNode : public Node {
^
./DoublyLinkedList.h:9:18: error: type 'Node<int>' is not a direct or virtual base of 'DLLNode<int>'
DLLNode<T>() : Node<T>(), prev() {}
^~~~~~~
driver.cc:6:15: note: in instantiation of member function 'DLLNode<int>::DLLNode' requested here
DLLNode<int> test;
I don't understand why the class Node isn't being recognized as a class as my compiler has claimed by the first error. Any tips would be greatly appreciated.
My compiler is Apple LLVM version 6.0 (clang-600.0.57) (based on LLVM 3.5svn)
You need to pass the template type parameter to your templated base class, when inheriting:
template <typename T>
class DLLNode : public Node<T> {
// ^^^
// ...
};
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.