What is this meaning of the *head follows the struct here?
struct node{
int data;
struct node *next;
}*head;
head is a pointer variable to struct node. This is equivalent of writing:
struct node{
int data;
struct node *next;
};
struct node *head;
On another note, though this is perfectly valid C++, this concept and your code is much related to C. However, if you use C++ compiler then you can simply write node *head;, i.e. on C++ you can omit the struct portion while declaring the head pointer.
This is the same as writing
struct node{
int data;
struct node *next;
};
node* head;
I dont really remember why, but it is more common in C to write it like your version.
Related
I know that the code below works.
int* pn;
pn = new int;
So I tried to apply it in same way, in my custom class.
class Matrix {
private:
typedef struct ex_node* ex_pointer;
typedef struct ex_node {
int ex_data;
ex_pointer next;
};
public:
void examplefunction() {
ex_pointer node;
node = new ex_node; //error here
}
};
The error says that I cannot assign "ex_node*" type value to "ex_pointer"type entity.
But ex_pointer is defined as ex_node*.
Is ex_pointer different type from ex_node*?
How can I remove this error?
I like the question and Jason Liam already provided different ways to fix your code. But I'd like to answer your first questions, which are entirely valid: "The error says that I cannot assign "ex_node" type value to "ex_pointer"type entity. But ex_pointer is defined as ex_node*. Is ex_pointer different type from ex_node*?"
Let's check exactly what the compiler says:
error: incompatible pointer types assigning to 'Matrix::ex_pointer' (aka 'ex_node *')
from 'Matrix::ex_node *'
node = new ex_node;
^~~~~~~~~~~
So, the problem is that node is of type Matrix::ex_pointer, that is a ex_node *. new ex_node instead is of type Matrix::ex_node *. The former is a pointer to a struct ex_node defined in the global namespace, while the latter is a pointer to a struct ex_node defined within class Matrix.
Apparently forward declaring a struct within a typedef assumes that the struct is in the global namespace, which in your case is not correct. You can fix it (as suggested also by Jason Liam) by forward declaring your struct before the typedef:
class Matrix {
struct ex_node;
typedef struct ex_node* ex_pointer;
struct ex_node {
int ex_data;
ex_pointer next;
};
public:
void examplefunction() {
ex_pointer node;
node = new ex_node;
}
};
Finally: don't hide that pointer behind a typedef.
A more C++ way(and correct way) of doing this would be remove the unnecessary typedefs as shown below:
class Matrix {
private:
struct ex_node {
int ex_data;
//------vvvvvvvv---------->directly using ex_node* is more clear IMO
ex_node* next;
};
using ex_pointer = ex_node*;
public:
void examplefunction(){
//------vvvvvvvvvv---------->you can use ex_pointer if you really want
ex_pointer node;
node = new ex_node;; //works now
}
};
Demo
Method 2
If you want you can still use alias as shown below. Here we provide a forward declaration for ex_node inside the Matrix so that we can use typedef/using with it.
class Matrix {
private:
struct ex_node; //forward declaration
using ex_pointer = ex_node*;
struct ex_node {
int ex_data;
//------vvvvvvvvv---------->use ex_pointer
ex_pointer next;
};
public:
void examplefunction(){
ex_pointer node;
node = new ex_node;;
}
};
I am creating a linked list implementation of the stack. In the Node struct, I have the data members data and next. My question is, why does the data member next need to be declared like struct Node * next and not just like Node *next?
template <class T>
class Stack{
private:
struct Node{
T data;
struct Node *next; //This is what the question is in reference to
};
Node *front;
Node *end;
public:
};
It is possible to write Node *next; instead of struct Node *next; in this context, and it does not change the meaning. The inclusion of the keyword struct is superfluous, and if I had to guess, the author included it because they are accustomed to writing in C, where (in contrast to C++) it may not be omitted.
In C++ these two structure definitions
struct Node{
T data;
struct Node *next;
};
and
struct Node{
T data;
Node *next;
};
are equivalent. Within the structure definition the name Node is the injected class name.
From the C++ 20 Standard (6.4.2 Point of declaration)
8 The point of declaration for an injected-class-name (11.1) is
immediately following the opening brace of the class definition.
Opposite to C++ in C this structure definition
struct Node{
T data;
Node *next;
};
is invalid because the name Node used as a tag name in this record struct Node and the name Node used in this member declaration Node *next; belong to different name spaces. The name Node in this declaration of data member
Node *next;
is not yet declared.
You could make the structure definition in C valid by using a typedef like
typedef struct Node Node;
struct Node{
T data;
Node *next;
};
Pay attention to that if you want to define a stack then the data member
Node *end;
is redundant.
I have a queue.h file like the following.
Is it possible that I can access the head pointer of the queue from Main?
If yes, what should I do in main?
Since the head pointer is a class pointer, and its type is a protected nested class, I don't think I can access it from main.
Therefore, I try to create a function getHead() as public member. However, another problem comes, it is I am using template class. Please guide me how to solve this problem.
my header file:
#include <iostream>
#include <iomanip>
using namespace std;
class PCB
{
public:
int PID;
string fileName;
};
template<class T>
class myQueue
{
protected:
class Node
{
public:
T info;
Node *next;
Node *prev;
};
Node *head;
Node *tail;
int count;
public:
void getHead(Node **tempHead);
};
template<class T>
void myQueue<T>::getHead(Node **tempHead)
{
*tempHead = head;
}
#endif
my main is:
#include "myQueue.h"
#include <iostream>
int main()
{
myQueue<PCB> queue;
//How can I access the Head pointer of my Queue here?
//queue.getHead(&tempHead);
return 0;
}
To acess myQueue::Node from outside the class you need to rewrite your getter function a bit:
template<class T>
myQueue<T>::Node* myQueue<T>::getHead()
{
return head;
}
Then you can use it in main() like this
auto head = queue.getHead();
Note that the usage of auto is important in this case. You still cannot declare any variable of type myQueue<T>::Node or myQueue<T>::Node** outside of myQueue<T>, but you can use auto variables to hold these types.
I'm trying to adapt a bit of code for a doubly-linked list to be included and used in my mysh.cpp file, and I'm getting
error: aggregate ‘linked_list list’ has incomplete type and cannot be defined
on compile. readcommand.cpp compiles just fine, so I'm just trying to figure out what needs to be changed either in the header file or cpp files to get it running smoothly for mysh.
Here are the relevant portions of the files used:
mysh.cpp
#include "readcommand.h"
using namespace std;
int main (int argc, char** argv) {
readcommand read;
linked_list list; // THIS is the line that's causing the error
...
}
readcommand.h
#ifndef READCOMMAND_H
#define READCOMMAND_H
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
class readcommand {
public:
// Struct Definitions
typedef struct node node_t;
typedef struct linked_list linked_list_t;
struct node;
struct linked_list;
...
};
#endif
readcommand.cpp
#include "readcommand.h"
using namespace std;
struct node {
const char *word;
node *prev;
node *next;
};
struct linked_list {
node *first;
node *last;
};
...
It's been a while since I've used headers in c++, or the language in general. I've tried changing the line in question to
read.linked_list list;
and
read.linked_list list = new linked_list;
and the like, but it just changes the error to things like
error: ‘class readcommand’ has no member named ‘linked_list’
and
error: invalid use of ‘struct readcommand::linked_list’
Thanks ahead of time.
You need to put these...
struct node {
const char *word;
node *prev;
node *next;
};
struct linked_list {
node *first;
node *last;
};
...someplace where the compiler will see them before they are used in class readcommand. Probably the easiest thing to do would be to put them in readcommand.h before class readcommand. The problem is that node and linked_list are being used in your class readcommand but the compiler doesn't know what they are at that point in the compilation.
The struct/class definition (and not just declaration) needs to be visible when you
dereference a pointer to that struct/class
create an object of that struct/class
The compiler needs to know the size of the object and the location of its fields.
That is why you may want to put the definitions of node and linked_list into the .h file.
Typically, you put into .cpp only the definitions of member functions.
You have the definition of linked_list in the cpp file... so if you include the .h file, the compiler doesn't see that struct's definition.
Move the struct's definition to the header file.
In readcommend.h
linked_list is a member of class readcommand, you can access it through readcommand object or move linked_list to readcommand.h insead if readcommand.cpp so compiler know "what is it"
Related to C++ Basics.
I am creating a singly linked list.
class Linked_List
{
public: Linked_List();
~Linked_List();
//Member Functions
struct node* getHead(void);
private:
struct node{
int d;
struct node* next;
}*head;
};
struct node (Linked_List::*getHead)(void)
{
return head;
}
I am getting this error:
"error C2470: 'getHead' : looks like a function definition, but there is no parameter list; skipping apparent body".
I tried to search in google but of no use. Any suggestions plz.
You don't need a pointer to member function, you just want to provide a definition for that function:
Linked_List::node* Linked_List::getHead()
{
return head;
}
Also notice, that the struct keyword is unnecessary in the function definition, while you have to qualify the name of the struct node with the name of the class in the scope of which it is defined.
Also, the void keyword to specify an empty argument list is unnecessary. I therefore suggest you to rewrite the class definition as follows:
class Linked_List
{
private:
struct node
{
int d;
struct node* next;
};
node *head;
public:
Linked_List();
~Linked_List();
node* getHead();
};