For Example:
graph.h
#ifndef GRAPH_H
#define GRAPH_H
#include <iostream>
#include <string>
using namespace std;
class graph
{
private:
struct node
{
string name;
int currentValue;
struct node *next;
};
node* head;
public:
graph();
~graph();
graph(string* newName, int* givenValue);
}
#endif
graph.cpp
#include "graph.h"
graph::graph() {}
graph::~graph() {}
graph::graph(string* newName, int* givenValue)
{
//This is what I want to achieve
this->node->name = newName; //Compile error
}
main.cpp
#include "graph.h"
#include <iostream>
using namespace std;
int main()
{
return 0; //Note I have not yet created a graph in main
}
How can I access the struct node members for the function above?
This is the error:
graph.cpp: In constructor ‘graph::graph(std::string*, double*)’:
graph.cpp:24:8: error: invalid use of ‘struct graph::node’
this->node->label = newName;
The problem has nothing to do with your private struct. The constructor should be able to access all private members.
The problem as that you confused the struct name node and the variable name head:
this->node->name = newName; // incorrect
Instead you should write:
this->head->name = *newName;
If you want to access the class variable you should call
this->head->name = *newName;
though you can omit this-> so the following is fine
head->name = *newName;
Couple of other notes:
string* newName is a pointer so you need to access its value with the dereference operator "*" (i.e. head->name = *newName; instead of head->name = newName;
node* head is a pointer and currently you are trying to access an uninitialized pointer. You probably need something like head = new node(); as well.
Your problem is not related to private access. First, add ; to end your class declaration:
class graph
{
// ...
};
Then, you typed this->node->name while nodeis a type. Change this line for this->head->name. Note that the pointer head is uninitialized here.
And then, newName is of type string* while this->head->name is of type string. Depending on how you want to use your class, you may consider modifying your code like this:
graph::graph(const string& newName, int givenValue):
head(new node)
{
//This is what I want to achieve
this->head->name = newName;
}
Or like this:
graph::graph(string* newName, int* givenValue):
head(new node)
{
//This is what I want to achieve
this->head->name = *newName;
}
Also, read about rule of 3/5/0.
Related
I am implementing a LinkedList in C++. After initializing the LinkedList, the value of the head is returned correctly (0). However, after calling another function from the LinkedList, the value of the head suddenly changes (825533248 is outputted). This seems strange, considering that I did not make any modifications to the head between initializing the LinkedList and calling the function.
Below is my class declaration (declaration.hpp):'
#include <iostream>
#include <fstream>
using namespace std;
class LinkedList
{
private:
Node *head;
public:
LinkedList(int v);
void insert(int v);
static void solution();
};
typedef struct Node
{
int val;
bool flag;
Node *next;
} Node;
And below is the implementation of my class:
#include <fstream>
#include <sstream>
#include "datastructure.hpp"
using namespace std;
void LinkedList::insert(int v)
{
cout << head->val << endl; // OUTPUTS 825533248
}
LinkedList::LinkedList(int v)
{
Node headNodeObject = {v, true, NULL};
head = &headNodeObject; // Convert head from object to pointer
}
void LinkedList::solution()
{
LinkedList linkedList = LinkedList(0);
// Test insertion
linkedList.insert(1);
}
Below is my main.cpp:
#include <iostream>
#include <string.h>
#include <datastructure.hpp>
using namespace std;
int main(int argc, char const *argv[])
{
LinkedList::solution();
}
Node headNodeObject = {v, true, NULL};
This object is stack-allocated, which means it's destroyed at the end of its scope: your constructor. Keeping a pointer on it and dereferencing that pointer after it's destroyed is Undefined Behavior (might display junk, might crash, ...). Make an heap-allocated object instead:
head = new Node {v, true, NULL};
BUT it means you'll need to delete it in your destructor (and properly freeing a linked list in the right order is a non-trivial operation), otherwise you'll get a memory leak.
My advice: use std::unique_ptr<Node> instead of Node*.
Given the following snippet:
/* trie.h file */
using namespace std;
#include <list>
typedef struct tn {
char ch;
list<struct tn*> ptrs;
} TrieNode;
class Trie {
public:
static const TrieNode* EMPTY;
//... other member functions
};
/* trie.cpp file */
#include "trie.h"
// declare, define static variables of the Trie class
TrieNode* Trie::EMPTY = (TrieNode*) malloc( sizeof(TrieNode) ); // <-- seems to work fine
// the statements below seem to yield errors
Trie::EMPTY->ch = '.';
Trie::EMPTY->ptrs = nullptr;
I get the error: "This declaration has no storage type or type specifier" if I try to instantiate the struct member variables of the static constant variable EMPTY. I know storing EMPTYas a struct object rather than a pointer to the struct object would be easier but was curious how this would work. Thanks.
You can't put statements like Trie::EMPTY->ch = '.'; and Trie::EMPTY->ptrs = nullptr; in global scope, they can only be executed inside of functions, constructors, etc.
Try something more like this instead:
/* trie.h file */
#include <list>
struct TrieNode {
char ch;
std::list<TrieNode*> ptrs;
};
class Trie {
public:
static const TrieNode* EMPTY;
//... other member functions
};
/* trie.cpp file */
#include "trie.h"
// declare, define static variables of the Trie class
static const TrieNode emptyNode{'.'};
const TrieNode* Trie::EMPTY = &emptyNode;
Live Demo
In a namespace (outside any function) you may place only declarations.
Statements like these:
Trie::EMPTY->ch = '.';
Trie::EMPTY->ptrs = nullptr;
are not allowed to be placed in a namespace, because they are not declarations.
Moreover, this statement:
Trie::EMPTY->ptrs = nullptr;
does not make sense, because the object ptrs is not a pointer, and a std::list cannot be initialized from nullptr.
Pay attention to that instead of the C function malloc(), you should use the C++ operator new.
This definition:
TrieNode* Trie::EMPTY = (TrieNode*) malloc( sizeof(TrieNode) );
is also incorrect, because you forgot to specify the qualifier const.
It should be rewritten like this:
const TrieNode* Trie::EMPTY = new TrieNode { '.' };
Here is a demonstrative program
#include <iostream>
#include <list>
typedef struct tn {
char ch;
std::list<struct tn*> ptrs;
} TrieNode;
class Trie {
public:
static const TrieNode* EMPTY;
//... other member functions
};
// the definition below must be placed in a cpp module
// it presents here only for demonstration.
const TrieNode* Trie::EMPTY = new TrieNode { '.' };
int main()
{
return 0;
}
Before exiting the program you should free the allocated memory.
Instead of the raw pointer you could use the smart pointer std::unique_ptr.
I'm new in C++ and I have something to do with a linked list, and I don't know why it doesn't work, need help from a prof :O)
Here's my .h
#ifndef UnCube_H
#define UnCube_H
using namespace std;
class ACube{
public:
ACube();
struct Thecube;
private:
void PrintList();
};
#endif
My ACube.cpp
#include <iostream>
#include "ACube.h"
ACube::ACube(){
};
struct Thecube{
int base;
int cube;
Thecube * next ;
};
void ACube::PrintList(){
};
and finally my main.cpp
#include <cstdlib>
#include <iostream>
#include "ACube.h"
using namespace std;
int main()
{
ACube * temp;
temp = (ACube*)malloc(sizeof(ACube));
for (int inc=1; inc <=20 ; inc++){
temp->ACube->nombrebase = inc;
temp->cube = inc*inc*inc;
}
system("PAUSE");
return EXIT_SUCCESS;
}
Everything was working fine, but when I add these lines :
temp->ACube->nombrebase = inc;
temp->cube = inc*inc*inc;
I add error saying :
'class ACube' has no member named 'TheCube'
'class ACube' has no member named 'cube'
Can someone help me because I want to create my list and fill the cube with number.
Other thing I want to use THIS. in the print,
Maybe someone can teach me what's wrong and how to do it !
Thanks for any help
You don't need to have a struct inside your class.
#ifndef UnCube_H
#define UnCube_H
using namespace std;
class ACube{
public:
ACube();
int base;
int cube;
ACube * next ;
private:
void PrintList();
};
#endif
ACube.cpp
#include <iostream>
#include "ACube.h"
ACube::ACube(){
};
void ACube::PrintList(){
};
Also, this string is wrong:
temp->ACube->nombrebase = inc;
it should be just:
temp->base = inc;
Last but not least, this code doesn't create a linked list, because you don't do anything with the ACube::next pointer.
There are so many horrible problems in your code, I suggest you should learn more C++ knowledge before writing linked list.
1. What is nombrebase?
I think nobody can answer.
2. You must allocate C++ class by new key word instead of malloc.
new invokes not only allocation but also class constructor, while malloc allocates only.
3. Thecube should been defined inside ACube
Since the code in your main() refers the member cube in class Thecube, main() must know what it is.
4. The member next in class ACube is a pointer which points to what?
What does a pointer point to without initilization? You should initial it in constructor, and destroy it in destructor.
5. temp->ACube
ACube is a class type, you can access member object, but not a type.
6. Never using namespace into a header file
It would make the client of header file has name collision.
The following is the corrected code. Just no compile error and runtime error, but this is NOT linked list:
ACube.h
#ifndef UnCube_H
#define UnCube_H
class ACube{
public:
struct Thecube
{
int base;
int cube;
Thecube * next;
};
ACube();
~ACube();
Thecube *next;
private:
void PrintList();
};
#endif
ACube.cpp
ACube::ACube()
: next(new Thecube)
{
}
ACube::~ACube()
{
delete next;
}
void ACube::PrintList(){
}
main.cpp
#include <cstdlib>
#include <iostream>
#include "ACube.h"
using namespace std;
int main()
{
ACube * temp;
temp = new ACube;
for (int inc = 1; inc <= 20; inc++)
{
temp->next->base = inc; // <-- This is not linked list, you shall modify.
temp->next->cube = inc*inc*inc; // <-- This is not linked list, you shall modify.
}
system("PAUSE");
return EXIT_SUCCESS;
}
Situation: I am attempting to create a range of methods within a Nodes class, all of which will use a struct "listnode" composed of playerName (string) and next (listnode). I have created the struct within a header file as I will be using the struct in the main class also.
Error: When I compile, I get an unusual error, its an error "c4430: missing type specifier - int assumed. Note: C++ does not support default int" I get this error on like 8.
#ifndef STRUCTS_H
#define STRUCTS_H
#include <Windows.h>
#include <string>
typedef struct
{
string playerName;
listnode * next;
} listnode;
#endif
If you are compiling as C++ , you should be able to do:
struct listnode
{
string playername;
listnode* next;
};
(no need for typedef here)
If you want to be able to compile in C, you will need to use a tag-name for the struct:
typedef struct listnode_tag
{
string playername;
struct listnode_tag* next;
} listnode;
(Obviously string may need std::string to work in C++, and you should have a #include <string> in this file, just to make sure it's "complete" on its own).
string lives in the std namespace, so refer to it as std::string. You also don't need the typedef syntax in C++:
#include <string>
struct listnode
{
std::string playerName;
listnode * next;
};
Make it:
typedef struct listnode
{ ^^^^^^^^
std::string playerName;
^^^^^
struct listnode * next;
^^^^^^
} listnode;
It's giving me this error for lines 21 and 22, which are the ones I've noted. Judging from other cases with similar error messages, I've got a syntax error somewhere. I just can't figure out what.. Here's my .cpp file:
#include <iostream>
#include <cstdlib>
#include "deque.h"
using namespace std;
struct node{
int data;
node *prev;
node *next;
};
Deque::Deque(){
count = 0;
node->head->next = node->head; //error on this line
node->head->prev = node->head; //and this one
}
Here's my header file:
# ifndef DEQUE_H
# define DEQUE_H
class Deque
{
private:
int count;
class node *head;
public:
Deque();
~Deque();
int size();
void addFirst(int);
void addLast(int);
int removeFirst();
int removeLast();
int getFirst();
int getLast();
};
#endif
Correct code for these lines:
head->next = head;
head->prev = head;
Your variable is named head, and node is its type, but there is no member named node in your class Deque
struct node has no member named head, which is a problem.
Where is your node variable coming from in Dequeue()? Looks undefined given the code that you have posted. node is a type, not a variable.
In C++ there is no need to prefix each declaration of a struct type variable with struct. If it needs to be C compatible you can always typedef the struct as well.