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.
Related
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) {
// ...
}
I've created 2 header files. ListA.h and ListN.h
They both make their own use their own unique class List. When I compile my program (even though they have no way of knowing the other exists, it says the following error)
Im pretty sure it shouldnt be a redefinition, but it obviously is. Any help is appreciated.
ListA.h
#ifndef __LISTA_H_
#define __LISTA_H_
#include <iostream>
using namespace std;
class List{
public:
List(int = 0);
List(const List&);
~List();
};
#endif
ListN.h
#ifndef __LISTN_H_
#define __LISTN_H_
#include <iostream>
using namespace std;
class List{
public:
List(int = 10);
List(const List&);
~List();
};
#endif
ListA.cpp
#include "ListA.h"
using namespace std;
List::List(int mySize)
{
//...
}
ListN.cpp
#include "ListN.h"
#include <iostream>
using namespace std;
List::List(int size)
{
//...
}
Main
#include <iostream>
#include "ListN.h"
using namespace std;
int main()
{
List myList;
return 0;
}
Both cpp files are being compiled by the compiler. Thus, when the linker goes to link the files together, it gets confused, since there are multiple List classes.
To fix this, you could use namespaces, or you cold not expose at least one of the List classes.
Alternatively, if the idea was to be able to include ListN.h vs ListA.h for configuration purposes, this is the wrong way to do so. Either you should have a #define parameter for the header, or you should find some other way, such as through #ifdef. For example (I'm not 100% sure this would compile, but you get the idea):
List.h
#ifndef __LIST_H_
#define __LIST_H_
#ifndef LIST_PARAM
#define LIST_PARAM 0
#endif
#include <iostream>
using namespace std;
class List{
public:
List(int = LIST_PARAM);
List(const List&);
~List();
};
#endif
main.cpp
#include <iostream>
#define LIST_PARAM 10
#include "List.h"
using namespace std;
int main()
{
List myList;
return 0;
}
I personally don't like this method; it is much better to just pass the value in to the constructor:
int main()
{
List myList{ 10 };
return 0;
}
When linker trying to link find the definition / symbol for List, it does found in two different obj file and hence linker givers error. In visual studio error number : LNK2005
To solve this error, either:
To fix, add /FORCE:MULTIPLE to the linker command line options
Add the classes in two different namespaces which will avoid this error.
ListN.h
#ifndef __LIST_H_
#define __LIST_H_
#include <iostream>
using namespace std;
namespace ListN
{
class List{
public:
List(int = 10);
List(const List&);
};
}
#endif
ListN.cpp
#include "ListN.h"
#include <iostream>
using namespace std;
namespace ListN
{
List::List(int size)
{
//...
}
}
Main.cpp
#include <iostream>
#include "ListN.h"
int main()
{
ListN::List myList;
return 0;
}
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 {
....
};
}
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.
I'm new to C++ and need some help with namespaces.
Following are my 4 files:
node.h <--class interface
node.cpp <--implementation
testNodeFunctions.cpp
testNodeMain.cpp
//node.h
---------------------------------
#include <iostream>
using namespace std;
namespace namespaceName{
class Node {
private:
int data;
public:
void setData( int x);
int getData();
};
//and some more functions
}
//node.cpp
-------------------------------------
#include <iostream>
#include "node.h"
using namespace std;
namespace namespaceName {
//provides implementation of the memeber functions
int Node::getData() const{
return data;
}
void Node::setData(int x){
data=x;
}
}//namespace
//testNodeFunctions.cpp
-------------------------------------
#include <iostream>
#include "Node.h"
using namespace std;
using namespace namespaceName;
void showData(){
//creates a Node object and prints some stuff
Node a=37;
cout<<a.getValue()<<endl;
}
//testNodeMain.cpp
----------------------------------------------
#include <iostream>
#include "Node.h"
void showData();
int main(){
//calls methods from testNodeFunctions
showData();
}
I'm not sure if I'm defining the namespace currently.
How Do I call the showData() function from the testNodeMain.cpp file. Currently I'm getting linker error stating that "undefined reference to namespaceName::Node::methodname"
Thanks so much in advance
Okay. That make sense. I removed , using namespace std from header. I'm compiling the testNodeMain.cpp which has the main(). the TestNodeMain.cpp calls functions from testNodeFunctions.cpp. testNodeFunctions.cpp creates Node object.
In your header file node.h, you have
void setData( int x);
int getData();
where as in your node.cpp file, you have:
int Node::getValue() const{
return data;
}
void Node::setValue(int x){
data=x;
}
You need to change your Node::getValue() const {} to Node::getData() const {}, or change the names of the functions in your header files to int getValue() and void setValue (int x)
The function names in the header files for the class and the actual .cpp file should be the same.
It's really hard to tell without a complete compiling example that induces your problem, but it looks like you forgot to include node.cpp on your link line.
I'm not sure if I'm defining the namespace currently.
That looks fine, although without seeing what you've put inside it I can't say for sure.
How Do I call the showData() function from the testNodeMain.cpp file?
The function needs to be declared before you can call it. Add the following declaration, either after the #include lines in testNodeMain.cpp, or in another header file which must then be included from testNodeMain.cpp:
void showData();
Then you can call the function from main:
int main() {
showData();
}
Currently I'm getting linker error stating that "undefined reference to namespaceName::Node::methodname"
You need to make sure you're compiling and linking all the source files, not just the main one. If you're using GCC, the build command should look something like:
gcc -o testNode testNodeMain.cpp testNodeFunctions.cpp node.cpp
If you're still getting the error in that case, then check that you have actually implemented the methods. If you think you have, then please update the code in your question to include the implementation of one of the missing methods so we can check that for you.