Why can't I make this object declaration in my class? - c++

When I do this, my compiler complains. There are 3 errors that emerge, though no error messages visible:
#include <stdlib.h>
#include <vector>
#include <string>
#include "ParseException.h"
#include "CycleFoundException.h"
#include "UnknownTargetException.h"
using namespace std;
class Maker
{
private:
vector<Node> storage;
public:
Maker(string file) throw (ParseException, CycleFoundException, UnknownTargetException);
vector<string> makeTarget(string targetName);
};
struct Node
{
string target;
vector<string> dependencies;
string command;
int discoverytime;
int finishtime;
int visited;
Node* next;
};
The compiler does not like my vector<Node> storage declaration. When I do vector<int> storage instead, it compiles without complaint. Is it wrong to declare an object of one class in another class? I thought this was alright.

Looks like you need to put the definition of Node before the definition of Maker.
You use the type name Node in the definition of Maker (in the line vector<Node> storage), but because you haven't defined Node yet the compiler doesn't know what it is.

Related

Pointer to struct defined in another file

Is it possible to point to a struct which was defined in another file from within a class?
I tried it like in the code below but get this error:
cannot convert 'main()::list*' to 'entry::list*' in assignment
main.cpp:
#include "entry.h"
#include <vector>
int main()
{
struct list
{
std::vector<entry*> entryVector;
int temp;
};
list A;
entry B;
B.ptrToStruct = &A;
return 0;
}
entry.h:
#ifndef ENTRY_H
#define ENTRY_H
#include <string>
class entry
{
public:
struct list; //prototype does not work
std::string text;
struct list* ptrToStruct;
};
#endif // ENTRY_H
I also tried to write the prototype like this:
struct main::list;
That didn't work either because "'main' has not been declared".
This is about scope. When you declare list inside entry that is a new type entry::list.
If you want a global type list you should move the struct list; to the global scope outside the class.
You might want to do the same thing with the declaration inside main.

C2011 'Node':'class' type redefinition

I am implementing bptree using c++. I am am stuck in the initial step of node creation. Keep getting "C2011 'Node':'class' type redefinition" error. I found some suggestions online to remove class key word from cpp file. But when I remove class keyword I get lots of other errors. here is my code for Node.cpp:
#include "Node.h"
#include <cstdio>
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Node {
bool leaf;
Node** kids;
map<int, string> value;
int keyCount;//number of current keys in the node
//constructor;
Node::Node(int order) {
this->value = {};
this->kids = new Node *[order + 1];
this->leaf = true;
this->keyCount = 0;
for (int i = 0; i < (order + 1); i++) {
this->kids[i] = NULL;
}
}
};
and Node.h file is as following:
#pragma once
#ifndef NODE_HEADER
#define NODE_HEADER
class Node {
public:
Node(int order) {};
};
#endif
How can I fix this?
Problem
In C++, headers are simply pasted into the body when you #include. So now the compiler sees:
class Node {
public:
Node(int order) {};
};
// stuff from system headers omitted for brevity
using namespace std;
class Node {
bool leaf;
//...
};
There are two problems here:
compiler sees class Node twice with different bodies.
Node::Node is defined twice (first time empty {}).
Solution
The header should include class declaration:
#include <map>
using namespace std;
class Node {
bool leaf;
Node** kids;
map<int, string> value;
int keyCount;//number of current keys in the node
//constructor;
Node(int order);
};
Note that the constructor has no body here. It's just a declaration. Because it uses map you need to include <map> and add using namespace before the declaration.
After that don't put class Node again in the .cpp or .cc file. Only put the method implementations at the top level:
Node::Node(int order) {
// ...
}

error C2923: 'std::vector' : 'Edge' is not a valid template type argument for parameter '_Ty'? [duplicate]

This question already has answers here:
Circular C++ Header Includes
(6 answers)
Closed 7 years ago.
Hi...
#ifndef Node_H
#define Node_H
#include <vector>
#include <stack>
#include <string>
#include <iostream>
#include "Edge.h"
#include "CongestionMap.h"
using namespace std;
class Node
{
public:
Node(){ visit = false;};
Node(int id);
~Node();
int getID();
void setLocation(int &row, int &col, GridCell *Gc);;
void displayList();
private:
int row;
int col;
int id;
bool visit;
int parrent;
int distance;
typedef vector< Edge > adjNodeList;
};
#endif
When i compile the project i get error as
project\node.h(43): error C2065: 'Edge' : undeclared identifier
project\project\node.h(43): error C2923: 'std::vector' : 'Edge' is not a valid template type argument for parameter '_Ty'...
please help me ...
Edge.h
#ifndef Edge_H
#define Edge_H
#pragma once
#include <vector>
#include <stack>
#include <string>
#include <iostream>
#include "Node.h"
using namespace std;
class Edge
{
public:
Edge() {};
Edge(Node *firstNode, Node *secNode, int inCost);
~Edge(void);
Node* getDstNode();
Node* getOrgNode();
int getCost();
private:
Node *orgNode;
Node *dstNode;
int cost;
};
#endif
As some commenters have noted, you have circular references. The code is parsed in the order it appears.
If we start in node.h, early on, it includes edge.h.
edge.h includes node.h, but that cleverly won't do anything because of the #ifdef protection, and the redundant #pragma once (they both achieve the same thing, so you might consider sticking to just one approach).
Ok, the first class definition we would encounter is that for Edge. Great, except that it refers to Node, and nobody knows what that is...because we're still in the code for edge.h that's been included into node.h.
Likely you have things happening the other way around and edge.h is being included first. The next thing that happens is that node.h is included, and it declares Node, which expects to know what Edge is, but nobody has seen that yet.
So you'll need to use forward declaration, that is in edge.h before you declare class Edge, add a line indicating what Node is:
class Node;
and conversely in node.h, provide a forward declaration for Edge. The second one is to cover the case where somebody includes node.h before they include edge.h.
As an example, if you had them both declared in the same file you would still need to do something like:
class Node; // forward declaration so that compiler knows that
// Node is a class when it gets to parsing Edge
class Edge {
...
private:
Node *orgNode;
};
class Node {
....
};
}

How to solve - syntax error : missing ';' before '<'

I have been receiving this error and it appears to be too vague for a Google search so I am handing it over to you! I am trying to create a linked list object that holds Account objects.
#include "Customer.h"
#include "LinkedList.h"
#include "Account.h"
#include "Mortgage.h"
#include "CurrentAcc.h"
#include "JuniorAcc.h"
#include "transaction.h"
#include <iostream>
#include <string>
using namespace std;
string name;
string address;
string telNo;
char gender;
string dateOfBirth;
list<Account> accList; // Error
list<Mortgage> mortList; //Error
I feel that I am not properly declaring my Linked Lists but cannot think of how else to do it.
The next piece of code I feel is as a result of my bad declaration.
void Customer::openCurrentAccount(int numb, double bal, int cl, string type, double Interest){
Current acc(numb,bal,cl,type,Interest); //Error - Expression must have class type.
accList.add(acc);
}
And here is the creation of my Linked List class .h file.
#pragma once
#include <iostream>
using namespace std;
template <class T>
class node;
template <class T>
class list
{
public:
list() { head = tail = NULL; }
~list();
void add(T &obj);
T remove(int ID);
void print(ostream &out);
T search(int ID);
private:
node<T> *head, *tail;
};
template <class T>
class node
{
public:
node() {next = NULL;}
//private:
T data;
node *next;
};
template <class T>
list<T>::~list()
{
}
You're defining your own class called list in the global namespace, and also putting using namespace std; in its header to dump the entire standard library into the global namespace. This means that you have two templates called list available in the global namespace, which will cause ambiguities and hence compile errors.
You should:
avoid putting using namespace std; in source files
never put it in headers, since it imposes namespace pollution on anyone who uses that header
avoid putting your own declarations in the global namespace
avoid giving your own declarations the same name as things in the standard library
use standard library facilities rather than writing your own versions.

C2071 illegal storage class, external vector declared in class and used in other classes

error C2071: 'Lexicon::list' : illegal storage class
I have a class that reads a bunch of strings into memory and then provides functions that allow applying operations on those strings and their relationships. As part of this I'd like to have a shared memory between the main.cpp where some of the operations are initiated and the class where the operations are completed. For this, in a previous post, it was suggested to use an extern type. But, now there is an error. How do I resolve this error and have a memory space shared by several classes?
in lexicon.h
#ifndef _lexicon_h
#define _lexicon_h
#include <string>
#include <vector>
using namespace std;
class Lexicon {
public:
Lexicon();
~Lexicon();
extern vector<vector<string>> list;
void buildVectorFromFile(string filename, vector<vector<string>> &list, int v, int h);
private:
struct charT { char letter; nodeT *next;};
};
#endif
in main.cpp
#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include "lexicon.h"
void buildVectorFromFileHelper (Lexicon & lex)
{
vector<vector<string>> list;
lex.buildVectorFromFile("ASCII.csv", list, 200, 2); //build 2x200 vector list
}
Ok, I missunderstood your previous question (this is what happens when you don't post full code). Inside a class, extern is not used:
in lexicon.h
#ifndef _lexicon_h
#define _lexicon_h
#include <string>
#include <vector>
using namespace std;
class Lexicon {
public:
Lexicon();
~Lexicon();
vector<vector<string>> list;
private:
struct charT { char letter; nodeT *next;};
};
#endif
in main.cpp
#include <string>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include "lexicon.h"
void buildVectorFromFileHelper (Lexicon & lex)
{
vector<vector<string>> list;
lex.buildVectorFromFile("ASCII.csv", list, 200, 2); //build 2x200 vector list
}
The problem here is that Lexicon doesn't have the method buildVectorFromFile, so how are you calling lex.buildVectorFromFile("ASCII.csv", list, 200, 2);?
To share the same vector, if it's a member, make it static:
class Lexicon {
public:
Lexicon();
~Lexicon();
static vector<vector<string>> list;
private:
struct charT { char letter; nodeT *next;};
};
In lexicon.cpp:
vector<vector<string>> Lexicon::list;
The rules of an extern memory is explained here in this daniweb thread; the comment there is that yes, this should be simple but it is somehow not intuitive. The gist is that the memory is globally declared with the extern prefix in .cpp file A and then to reuse the memory in cpp B, globally declare it again in .cpp file B.
I think Luchian_Grigore and #jahhaj were getting there but we had either just not found the words for me to understand or they were still finding the words to explain.