How do I make a class correctly? - c++

My class is not being defined correctly. What do I need to change to make it work? My ExpTree will not work at all, when I go to the implementation file it will not compile, and will give me an error for my class, constructor and destructor. It says that ExpTree is an anonymous struct.
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#ifndef ExpTree
#define ExpTree
using namespace std;
class ExpTree{
public:
ExpTree() {root = NULL;}
~ExpTree();
void build (istream& in_s);
void prefix (ostream& out_s);
void infix(ostream& out_s);
void postfix(ostream& out_s);
int value();
private:
struct Node
{
int operand;
char optr;
Node *left;
Node *right;
};
Node *root;
void destroy(Node* root);
Node* help_build (istream& in_s);
void print_prefix(ostream& out_s, Node* r);
void print_infix(ostream& out_s, Node *r);
void print_postfix(ostream& out_s, Node *r);
int find_value(Node *r);
};
#endif

Don't use the same name for your #define include guard and anything else.
#define ExpTree tells the "preprocessor" to "learn that ExpTree means an empty piece of source code". This does have the desired effect that if the header gets included additional times, the contents will be skipped since the #ifndef will notice that the preprocessor already knows a meaning of ExpTree.
But, with the ExtTree name being used this way, it has the undesired effect that every time ExpTree appears later in your code, it gets replaced with empty code! So the "compiler" sees code like this:
class {
public:
() {root = NULL;}
~ ();
// ...
Which yes, will produce tons of errors.
There are a number of common patterns for include guards, like #define PROJECTNAME_EXPTREE_H. You want to try to reduce the chance it will ever be the same as a name some other code uses.
P.S. It's common practice to put #include directives inside the #ifndef ... #endif guard too. If your header was already seen, those headers were already included and don't need to be re-scanned again.

Related

"was not declared in this scope" in c++

This is my header file
#ifndef LinkedList_H
#define LinkedList_H
#include <iostream>
#include "Node.h"
class LinkedList {
public:
int length;
// pointer to the first element of LinkedList
Node *head = 0;
// pointer to the last element of LinkedList
Node *tail = 0;
LinkedList();
~LinkedList();
};
#endif
and this is my.cpp file
#include "LinkedList.h"
using namespace std;
LinkedList::LinkedList() {
head=tail;
this->length=0;
}
LinkedList::~LinkedList() {
Node *current = head;
while(current!=NULL){
Node *temp = current;
current=current->next;
delete temp;
}
}
void add(string _name, float _amount){
Node *node = new Node(_name, _amount);
while(head==NULL){ //here, there is an error.
head=node;
head->next=tail;
}
}
int main(){
LinkedList *list = new LinkedList();
add("Adam", 7);
cout<<list->head<<endl;
}
In my .cpp file when I want to try to make an add function, it gives me an error in the while loop condition in add function. It says "head was not declared in this scope". But I declared in .h file. I couldn't see what is wrong.
You should use the resolution scope operator, just like you did for the constructor and the destructor.
So, you in your source file do this:
void LinkedList::add(string _name, float _amount) {
And then, of course, declare that function inside your class, in the header file.
Very likely the problem is circular includes. You probably have Node.h including LinkedList.h and vice-versa. This leads to (essentially) a paradox: If both class definitions require the other, which of the two is defined first in any given compilation unit?
In practice, you include Node.h, which then tries to include LinkedList.h again (note that #include literally means "copy-paste this file here" to the compiler), but at this point LinkedList_H is already defined (because that's where you came from) and the include has no effect. So now you are in the middle of Node.h but with no prior definition of LinkedList and get "not declared" errors.
The solution is to remove the #include Node.h in LinkedList.h and replace it with a forward declaration, since the LinkedList definition in the header doesn't need to know anything more than "the class Node exists" (because it only uses pointers).

one class is not detecting the other class's object [duplicate]

This question already has answers here:
Resolve build errors due to circular dependency amongst classes
(12 answers)
Closed 8 years ago.
I have two classes Node and Wire. I am getting an error for the line vector<Wire*> inputs;
Node.h
#ifndef NODE_H_
#define NODE_H_
#include "wire.h"
class Node{
private:
bool sorted;
TGate gateType;
string name;
vector<Wire*> inputs;
vector<Wire*> outputs;
int state;
}
#endif /* NODE_H_ */
Wire.h
#ifndef WIRE_H_
#define WIRE_H_
#include "Node.h"
class Node;
class Wire{
private:
Node* input;
Node* output;
public:
Wire(Node* a, Node* b);
//void setInput(Node* in);
//void setOutput(Node* out);
Node* getInput();
Node* getOutput();
};
#endif /* WIRE_H_ */
wire.cpp
#include "wire.h"
#include"node.h"
class Node;
Wire::Wire(Node* a, Node* b)
{
}
node.cpp
Node::Node(TGate gT, string name)
{
std::cout<<"\nNode created is: "<<name<<"\n";
}
ERROR: /src/node.h:29:9: error: ‘Wire’ was not declared in this scope
In the headers, replace
#include "Node.h"
with
class Node;
and the same for wire.
You have mutually including #includes, so "wire.h" has to include "Node.h" which has to include "wire.h", which has to include.... You need to break this chain, and to do that you use forward declarations.
The compiler needs to know that Node and Wire are classes. Since the #include files only refer to pointers to the other class, the compiler doesn't need to know the class layouts. This removes the mutual dependency and means the compiler can read all the code.
You also should have include guards, to prevent your headers from being compiled twice and causing redefinitions. Some compilers allow #pragma once, and all can handle something like
#ifndef MY_WIRE_H
#define MY_WIRE_H
...
#endif
One stylistic note: you've got Node and Wire, but "Node.h" and "wire.h". It will be easier to keep track of your files if they're consistently capitalized.

error: expected ')' before '*' token

I'm having a problem with the constructor signature in the header below. The compiler gives me the message:
error: expected ')' before '*' token
Can anybody tell me what I might be missing here?
#ifndef PRIORITYQUEUE_H
#define PRIORITYQUEUE_H
#include <iostream>
#include <cstdlib> //We'll need to use srand() and rand() as well as clock()
#include <ctime>
#include <vector>
#include <list>
#include "Graph.h" //header for Graph class
using namespace std;
class PriorityQueue
{
public:
PriorityQueue(Graph*):infiniteDist(9999);
void set_previous_node(int, int);
int get_node_value(int);
void set_node_value(int, int); //Change the node value of an element
void markVisited(int);
bool contains(int); //Does the queue contain a particular vertex?
void insertIntoQueue(int);
int top(); //pick an unvisited node with the shortest distance.
int queueSize();
void print();
private:
class vertexNode {
public:
int nodeNum;
int nodeValue;
int previousNode; //previous node visited with shortest distance from source
bool wasVisited;
};
vector<vertexNode> nodeValues;
const int infiniteDist; //value to represent infinite distance
int nodeQuantity;
};
#endif // PRIORITYQUEUE_H
The actual constructor is used as in:
PriorityQueue::PriorityQueue(Graph* graph):infiniteDist(9999)
{
...
}
You are trying to partially declare the constructor by using an initialiser expression, in the declaration of PriorityQueue(Graph*):infiniteDist(9999);. This is not allowed. The declaration (generally in the .h file) should just be:
PriorityQueue(Graph* graph);
The definition (generally in the .cpp file) should then be:
PriorityQueue::PriorityQueue(Graph* graph)
: infiniteDist(9999)
{
...
}
The reason is simply that the initaliser list is already part of the definition, i.e. what the method does, rather than just a declaration of the name and return type. Imagine that you'd use a different number (say 42) in the declaration and another (9999) in the definition, which one should be used? Hence it is not allowed.
change this
PriorityQueue(Graph*):infiniteDist(9999);
to
PriorityQueue(Graph*);
PriorityQueue(Graph*):infiniteDist(9999); is wrong.
Either you define your whole constructor in the header 9ie add the body) or you only have to to declare it with PriorityQueue(Graph*);
The solution 2 is the best one.

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.

C++ linker error

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.