Im wanted to create a bidirectional association between 2 classes. For example class A has class B as its private attribute and class B has class A as its private attributes.
Errors which I have gotten is mainly:
Error 323 error C2653: 'Account' : is not a class or namespace name
Error 324 error C2143: syntax error : missing ';' before '{'
(i get loads of such error)
I believe these errors got to do with how i include paymentMode.h in account.h and vice versa. I tried commenting off one inclusion in one of the classes and things work fine. May I ask how to remove such errors while I can still have my bidirectional association between account and paymentMode class?
Thank you!
Attached are the codes that I have written.
//paymentMode.h
#pragma once
#ifndef _PAYMENTMODE_H
#define _PAYMENTMODE_H
#include <string>
#include <iostream>
#include <vector>
#include "item.h"
#include "account.h"
using namespace std;
class PaymentMode
{
private:
string paymentModeName;
double paymentModeThreshold;
double paymentModeBalance; //how much has the user spent using this paymentMode;
vector<Account*> payModeAcctList;
public:
PaymentMode(string);
void pushItem(Item*);
void addAcct(Account*);
string getPaymentModeName();
void setPaymentModeName(string);
void setPaymentModeThreshold(double);
double getPaymentModeThreshold();
void setPaymentModeBal(double);
double getPaymentModeBal();
void updatePayModeBal(double);
int findAccount(string);
void deleteAccount(string);
};
#endif
//account.h
#pragma once
#ifndef _ACCOUNT_H
#define _ACCOUNT_H
#include <string>
#include <iostream>
#include <vector>
#include "paymentMode.h"
using namespace std;
class Account
{
private:
string accountName;
//vector<PaymentMode*> acctPayModeList;
double accountThreshold;
double accountBalance; //how much has the user spent using this account.
public:
Account(string);
//void addPayMode(PaymentMode*);
//int findPayMode(PaymentMode*);
string getAccountName();
void setAccountName(string);
void setAccountThreshold(double);
double getAccountThreshold();
void setAccountBal(double);
double getAccountBal();
void updateAcctBal(double);
};
#endif
You have a circular include dependency, but in this case, since class A only holds a container of pointers of class B, and vice versa, you can use forward declarations, and put the includes in the implementation files.
So, instead of
#include "account.h"
use
class Account;
Unrelated: do not put using namespace std in header files, and if possible, nowhere. See here for more on that issue.
Related
I'm aware this question has been asked numerous times but I've tried several suggestions such as checking my spelling, making sure I included the header files, capitalization, etc, but I'm still getting the same error and can't figure out what's triggering it.
When I try to compile Student.h using g++ -c Customer.h I get the error 'Student' does not name a type on the line 'Student student;' for Login.h and I have no idea why. Can anyone try to pinpoint what's causing it? This variable is supposed to represent the student of this login id/account which is supposed to be a pointer to a Student object.
Likewise, when I try to compile Login.h, I get the error 'Login' has not been declared in Customer.h for bool addAcct(Login*) as well as the error 'Login' does not have a type for Login* logins[MAX_LOGINS].
Any help would be appreciated!
Student.h:
#ifndef STUDENT_H
#define STUDENT_H
#define MAX_LOGINS 4
#include <string>
#include "Login.h"
using namespace std;
class Student{
public:
Student(int = 0, string = "");
int getId();
bool addAcct(Login*);
void print();
private:
int id;
string name;
Login* logins[MAX_LOGINS];
int numberOfLogins;
};
#endif
Login.h
#ifndef LOGIN_H
#define LOGIN_H
#include <string>
#include "Student.h"
using namespace std;
class Login{
public:
Login(int = 0, float = 0);
int getNumber();
void setStudent();
void print();
private:
int number;
Student student;
};
#endif
Issue here is the circular dependency (as pointed out in the comments), and the problem with that is the processor essentially handles #include statements as sequential text insertions.
For example, when the preprocessor encounters #include "student.h", it goes step by step like:
#ifndef STUDENT_H // <--- header guard not defined at this point, ok to proceed
#define STUDENT_H // <--- define header guard first thing in order to prevent recursive includes
#define MAX_LOGINS 4
#include <string>
#include "Login.h" ---> #ifndef LOGIN_H
#define LOGIN_H
#include <string>
#include "Student.h" ---> #ifndef STUDENT_H
// entire body of student.h is skipped over
// because STUDENT_H header guard is defined
using namespace std; <--- // so processing continues here
class Login{
// ...
Student student; // <--- error because class Student is not defined
};
The solution is to forward declare types which do not require a full definition, instead of #include'ing the respective header.
In this case, class Login has a member Student student; which requires class Student to be fully defined, so login.h must in fact #include "student.h".
However, class Student only carries the Login* logins[MAX_LOGINS]; array of pointers to Login, and a pointer does not require a full definition of the class, but just a forward declaration of the type. Therefore Student.h can be modified to forward declare class Login instead, which removes the circular header dependency and allows the code to compile.
// #include "Login.h" // <--- full header not required
class Login; // <--- forward declaration is sufficient
I have the following header files within my code. I know that the problem is that a circular dependency is occurring but I can't seem to solve it.
Any help to fix it?
project.h gets me this ERROR: field ‘location’ has incomplete type
#ifndef PROJECT_H_
#define PROJECT_H_
#include <string.h>
#include "department.h"
class department;
class project{
string name;
department location;
public:
//constructors
//Setters
//Getters
};
#endif
employee.h gets me this ERROR field "‘myDepartment’ has incomplete type"
#ifndef EMPLOYEE_H_
#define EMPLOYEE_H_
#include "department.h"
#include <vector>
class department;
class project;
class employee
{
//attributes
department myDepartment;
vector < project > myProjects;
public:
//constructor
// Distructor
//Setters
//Getters
#endif
department.h
#ifndef DEPARTMENT_H_
#define DEPARTMENT_H_
#include <string.h>
#include "employee.h"
#include "project.h"
#include <vector>
class project;
class employee;
class department{
private:
string name;
string ID;
employee headOfDepatment;
vector <project> myprojects;
public:
//constructors
//Setters
//Getters
};
#endif
You have cyclical #includes.
Try removing #include "employee.h" and #include "project.h" from department.h.
Or vice versa.
You have an include tree like this which will cause you
problems:
project.h
department.h
employee.h
department.h
department.h
employee.h
project.h
normally it is better to make your headers as independent of
other class headers as possible, to do this keep your forward
declarations but remove the includes, then in the .cpp file
include the headers.
e.g.
class project;
class employee;
class department {
...
employee* headOfDepartment;
vector<project*> myprojects;
then in department.cpp
include employee.h and project.h and instantiate the members in your constructor, to make it even better use unique_ptr so you don't need to bother about deleting them:
class department {
...
std::unique_ptr<employee> headOfDepartment;
std::vector<std::unique_ptr<project>> myprojects;
another tip is to not have using namespace std in the header, instead include the namespace e.g. std::vector<...>
Error: Line 12 of Cell.h: 'Actor' undeclared identifier.
If I try to forward declare above it, it says that there's a redefinition. What do I do?
Actor.h:
#ifndef ACTOR_H
#define ACTOR_H
#include <iostream>
#include <vector>
#include <string>
#include "Cell.h"
using namespace std;
class Actor //Simple class as a test dummy.
{
public:
Actor();
~Actor();
};
#endif
Cell.h:
#include <iostream>
#include <string>
#include <vector>
#include "Actor.h"
#ifndef CELL_H
#define CELL_H
using namespace std;
class Cell // Object to hold Actors.
{
private:
vector <Actor*> test;
public:
Cell();
~Cell();
vector <Actor*> getTest();
void setTest(Actor*);
};
#endif
Cell.cpp:
#include "Cell.h"
#include <vector>
vector<Actor*> Cell::getTest() //These functions also at one point stated that
{ // they were incompatible with the prototype, even
} // when they matched perfectly.
void Cell::setTest(Actor*)
{
}
What else can I do?
Remove the #include "Cell.h" from Actor.h and you're set to go.
In general, prefer forward declarations where you can, and includes where you must. I'd also replace the #include "Actor.h" from Cell.h with a forward declaration: class Actor;.
In the cpp files you can include the headers if you need them.
You have recursive #includes via your mutual references between cell.h and actor.h.
In Cell.h, delete #include <Actor.h>.
In Cell.h, add the line class Actor; just above the definition of class Cell.
In Cell.cpp, you might need to add #include "Actor.h".
What is going on?
#include "MyClass.h"
class MyOtherClass {
public:
MyOtherClass();
~MyOtherClass();
MyClass myVar; //Unknown type Error
};
Suddenly when I include the .h and write that var Xcode gives me tons of errors... and also the unknown type error.
How can it be unknown when the .h is included right there?
Here is the NodeButton.h file which would correspond to the MyClass.h in the example
#pragma once
#include "cinder/Vector.h"
#include "cinder/gl/gl.h"
#include "cinder/gl/Texture.h"
#include "cinder/Color.h"
#include "cinder/ImageIo.h"
#include "cinder/Timeline.h"
#include "cinder/app/AppBasic.h"
#include "cinder/App/App.h"
#include "Node.h"
#include "CursorMano.h"
using namespace ci;
using namespace ci::app;
using namespace std;
using namespace is;
typedef boost::shared_ptr<class NodeButton> NodeButtonRef;
class NodeButton : public Node2D
{
public:
NodeButton (CursorMano *cursor, string imageUrl, bool fadeIn = false, float delay = 0.0f);
virtual ~NodeButton ();
//methods
void update( double elapsed );
void draw();
void setup();
//events
bool mouseMove( ci::app::MouseEvent event );
//vars
CursorMano *mCursor;
gl::Texture mImageTexture;
Anim<float> mAlpha = 1.0f;
bool mSelected = false;
private:
};
And here are the contents of CursorMano.h which would correspond to MyOtherClass.h in the example.
#pragma once
#include <list>
#include <vector>
#include "cinder/app/AppBasic.h"
#include "cinder/qtime/QuickTime.h"
#include "cinder/gl/Texture.h"
#include "cinder/Vector.h"
#include "NodeButton.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class CursorMano {
public:
CursorMano (AppBasic *app);
~CursorMano ();
void mueveMano(Vec2i);
void update();
void draw();
void play(int button);
void reset(int button);
Vec2i mMousePos;
NodeButton mButtonCaller; //this gives the unknow type error
private:
AppBasic *mApp;
gl::Texture mFrameTexture;
qtime::MovieGl mMovie;
int mIdButton;
};
You have a circular dependency of your header files.
NodeButton.h defines NodeButton class which CursorMano.h needs to include so that compiler can see definition for NodeButton but NodeButton.h itself includes CursorMano.h.
You will need to use forward declarations to break this circular dependency.
In NodeButton.h you just use an pointer to CursorMano so You do not need to include the CursorMano.h just forward declare the class after the using namespace declarations.
using namespace std;
using namespace is;
class CursorMano;
It's probably a result of the circular dependency between you two header files (NodeButton includes CursorMano and CursorMano includes NodeButton). Try removing the #include "CursorMano.h" in NodeButton.h and add class CursorMano; before your NodeButton declaration.
So I am getting the following errors:
..\Actor.h:35: error: `Attack' is not a member of `RadiantFlux'
..\Actor.h:35: error: template argument 1 is invalid
..\Actor.h:35: error: template argument 2 is invalid
..\Actor.h:35: error: ISO C++ forbids declaration of `attacks' with no type
On this line (among others):
std::vector<RadiantFlux::Attack> attacks;
Here are the relevant files:
Actor.h:
#ifndef ACTOR_H_
#define ACTOR_H_
#include <string>
#include <vector>
#include "Attack.h"
namespace RadiantFlux {
...
class Actor {
private:
std::string name;
int health;
std::vector<RadiantFlux::Attack> attacks;
Attributes attributes;
public:
...
};
}
#endif /* ACTOR_H_ */
Attack.h:
#ifndef ATTACK_H_
#define ATTACK_H_
#include <string>
#include <stdlib.h>
#include <time.h>
#include "Actor.h"
namespace RadiantFlux {
...
class Attack {
private:
...
public:
...
};
}
#endif /* ATTACK_H_ */
Why am I getting these errors and what can I do to fix them? I am assuming it has something to do with the namespaces...
You have a cyclic dependency of your header files.
Attack.h includes Actor.h and vice versa.
Use Forward Declaration of class to avoid circular dependency problems.
Since the OP's comments, here is what needs to be done:
class Actor;
class Attack
{
};
If your code fails to compile after doing this, You need to read the linked answer and Understand why the error and how to solve it. The linked answer explains it all.
The classes Actor and Attack both refer to each other, so you will need to add a forward declaration in one of the file.
For example, in Actor.h:
class Attack;
class Actor
{
...
};