class and struct nesting - c++

I am not very clear about this code
outer is a class and the inner a struct, can anyone help me explain it?
class Stack {
struct Link {
void* data;
Link* next;
Link(void* dat, Link* nxt):
data(dat),next(nxt) {}
}* head;
public:
Stack():head(0) {}
~Stack() {
require(head==0,"Stack not empty");
}
void push(void* dat) {
head = new Link( dat, head );
}
void peek() const {
return head ? head->data : 0;
}
void* pop() {
if(head == 0) return 0;
void* result = head->data;
Link* oldHead = head;
head = head->next;
delete oldHead;
return result;
}
};
my question is focus on the first few lines
class Stack {
struct Link {
void* data;
Link* next;
Link(void* dat, Link* nxt):
data(dat),next(nxt) {}
}* head;
what the relation between class Stack and struct Link?

Link is declared inside Stack, and since it's private by default, it can't be used outside the class.
Also, Stack has a member head which is of type Link*.
The only difference between class and struct is the default access level - public for struct and private for class, so don't let "struct declared inside a class" confuse you. Other than the access level, it's the same as "class declared inside a class" or "struct declared inside a struct".

Class Stack and struct Link are nested.
Note that nested classes have certain limitations regarding accessing of elements of nested and the enclosing class.
Since, Link is declared under private access specifier in class Struct it cannot be accessed outside the class Struct.

Struct Link is inner-declared in the class (the correct term is nested). It can be accessed only in the class (due to its default private accessor level). The struct could have been referred with Stack::Link if it was declared public.
The reason for such declaration in this case is that only the inner methods of the class need to use the links and struct is providing better code organization. However as long as no other class needs to access the struct such declaration provides better encapsulation.

Related

Private Struct only returnable with private listed first in a class

So I have run into the case where returning an object of type Node is not allowed if the private variables have been listed after the public as can be seen by the two screenshots below. There CLion is giving me an error as can be seen with Node being red. I understand why this is, however I am wondering if there is anyway to fix this issue without placing/declaring private before public?
Public before private (Desired):
Private before public (what works):
Thanks!
The problem is that when the return type Node* is encountered in the member function getCurrentPalyer definition, the compiler doesn't know that there is a struct named Node. So you've to tell that to the compiler which you can do by adding a forward declaration for Node as shown below:
class Palyer
{ private: struct Node; //forward declaration added for Node
public:
Node* func()
{
return head;
}
private:
struct Node {};
Node* head;
};
Working Demo

How to access a private typedef as a parameter in a public function

Title says it all.
typedef string ListElemType;
class inord_list {
public:
void insertafter(const ListElemType&, link);
void insertbefore(const ListElemType&, link);
private:
struct Node;
typedef Node* link;
struct Node
{
ListElemType elem;
link next;
};
link head;
link tail;
link current;
link next;
Whenever I try to use the "link" as a parameter in the above functions it's an error.
Another question in the same scope as well, if I declared the 2 public functions as private, I can't call one in another. Why so ? even if:
this->insertafter(const ListElemType& elem, link p);
It gives me syntax error.
Whenever I try to use the "link" as a parameter in the above functions it's an error.
As it should be. You can't use a private type as a parameter/return value in a public method. Callers of the method that are outside of the class would not have access to the type, and thus could not call the method.
if I declared the 2 public functions as private, I can't call one in another.
Yes, you can.
Why so ? even if:
this->insertafter(const ListElemType& elem, link p);
It gives me syntax error.
Because it is a syntax error. The correct syntax would look more like this instead:
void inord_list::insertbefore(const ListElemType& elem, link p) {
this->insertafter(elem, p);
}
You can drop the this->, though:
void inord_list::insertbefore(const ListElemType& elem, link p) {
insertafter(elem, p);
}

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

invalid use of non-static data member 'linkedList<int>::dummyNode' c++

The dummyNode declaration variable was working well until i wrote iterator class as nested, now it gives me an error invalid use of non-static data member, 'linkedList::dummyNode' c++, if i removed iterator class it works well
template
class linkedList
{
private:
listNode<T> * head, *tail;
listNode<T> * dummyNode = new listNode<T>;
int sz = 0;
public:
class iterator
{
public:
iterator()
{
itrNode = head;
}
void operator ++ ()
{
try{
if(itrNode == dummyNode)
throw "Sorry this is the end of the list\n";
else
{
itrNode = itrNode->next;
}
}catch(const char * error)
{
cerr << error;
}
}
T& operator *()
{
return *(itrNode->value);
}
void operator -- ();
private:
listNode<T> * itrNode;
};
linkedList();
~linkedList();
linkedList(T value, int initial_size);
iterator begin();
};
A C++ nested class do not share data with its outer class -- if there were the case, each instance of the inner class would be in a one-to-one relationship with a corresponding instance of an outer class and would thus add no extra functionality. Instead, the main purposes of nested classes are:
Namespace meaning: linkedlist::iterator is more meaningful than linkedlist_iterator
Depending on the C++ version standard, a nested class has extra visibility of the member objects of instances of the outer class
Maybe others that I'm not aware of
The biggest problem in your code is the constructor of the iterator
iterator()
{
itrNode = head;
}
The data head means nothing in the context of the inner class, because its a data member of a linkedlist object -- again, the iterator does not belong to an instance of the linkedlist class. Instead the constructor should be something like
iterator(linkedlist<T>& list)
{
itrNode = list.head; // Might not work in C++03
}
There might be other changes you need to make regarding the templatization (I'm not sure; I haven't made nested templated classes before). Also, this type of constructor for the linked list should work, but doesn't follow standard paradigms. More standard would be adding functions
iterator linkedlist::begin();
iterator linkedlist::end();
to the linkedlist class. Even better would be to create begin(linkedlist&) and end(linkedlist&) functions. This is explained in this following SO post.

Details and benefits of using a struct in a class definition

Consider the following code:
class myclass
{
public:
//some public stuff
private:
struct classitem
{
int x;
classitem *next;
};
}
What I do not understand is this;
Is classitem just a definition, or will it already be a member of an object of this class? In other words, will it be filling any memory when we create an object of this class? If it is just a definition, how would we use it in future?
And what would be the benefits of using this struct in class definition instead of defining it outside of the class?
It will be just a definition.
If you want an object, use:
struct T { ... } instance;
The inner struct will be scoped in the outer struct definition - as to why it's useful, you can make the type (class) definition private for instance, if you don't want that type to be used outside of your class.
class NHeadedBeast {
struct Head {
Head() : numHeads{2}, eyesPerHead{4} { }
int numHeads;
int eyesPerHead;
} head;
public:
int getEyeCount() const {
return head.eyesPerHead * head.numHeads;
}
};
Notice how specific the Head class is - and also, it's called Head, which has a decent chance of colliding with some other type name. In other words, noone would ever want to use that Head type without my NHeadedBeast class, so might as well make the type inaccessible and isolate it in the NHeadedBeast scope.