I'd like to use toString with class argument, but for some reason there is an error.
The code is:
Animal.h
#include "Treatment.h"
#include "jdate.h"
#include <vector>
class Animal{
protected:
int id;
double weight;
int yy;
int mm;
int dd;
double accDose;
char sex;
vector<Treatment*> treatArray;
public:
Animal();
Animal(int newid, double newweight, int yy, int mm, int dd, char newsex, vector<Treatment*> treatArray);
~Animal();
};
Treatment.h
#ifndef TRE_H
#define TRE_H
#include <string>
#include <sstream>
#include "jdate.h"
#include "Animal.h"
#include "Cattle.h"
#include "Sheep.h"
class Treatment{
private:
int id;
jdate dayTreated;
double dose;
public:
Treatment(int id,jdate dayTreated, double dose);
Treatment();
~Treatment();
string toString(Animal* a);
};
#endif
Treatment.cpp
#include "Treatment.h"
using namespace std;
Treatment::Treatment(int newid,jdate newdayTreated, double newdose){
id=newid;
dayTreated = newdayTreated;
dose = newdose;
}
Treatment::Treatment(){
id=0;
dose=0;
}
Treatment::~Treatment(){}
string Treatment::toString(Animal* a)
{
string aa;
return aa;
}
toString is in Treatment class. I'm not sure but I think it's because Animal has
vector treatArray;. Does it actually matter?
Sorry that I cannot put the error messages here, because once I declare toString, for some reason tons of errors occur, such as
Error 1 error C2065: 'Treatment' : undeclared identifier l:\2011-08\c++\assignment\drug management\drug management\animal.h 30 1 Drug Management
// Animal.h
// #include "Treatment.h" remove this
class Treatmemt; // forward declaration
class Animal
{
...
};
In your version, Treatment.h and Animal.h include each other. You need to resolve this circular dependency using forward declaration. In .cpp files, include all necessary h-files.
You include Animal.h in Treatment.h before the class Treatment is defined, that's why you're getting the error.
Use forward declaration to solve this:
In Animal.h add line
class Treatment;
You've not used std namespace in both header files.
So, use std::string instead of string. Because string is defined in std namespace.
Simillarly use std::vector instead of vector.
There are a few problems with your code. First of all, Animal.h should have an include guard as Treatment.h has:
#ifndef ANIMAL_H
#define ANIMAL_H
// Your code here
#endif
I'd also suggest that you give a longer name to Treatment.h's guard, you'll reduce the risk of using the same name elsewhere.
Using guards will ensure that you don't have a circular inclusion. Still you do have a circular dependency because the Treatment class needs to know about the Animal class and vice versa. However, as in both cases you used pointers to the other class, the full definitions are not required and you can - should, actually - replace in both header files the inclusion of the other with a simple declaration. For instance in Animal.h remove
#include "Treatment.h"
and add
class Treatment;
Both Treatment.cpp and Animal.cpp must include both Treatment.h and Animal.h.
Related
Extreme c++ beginner here. I have a global variable i've tried placing into a separate header file, and also into the specific classes themselves. Throughout, i'm receiving a "redefinition" error.
Here are the global variables:
enum GRADE {F, D, CMINUS, C, CPLUS, BMINUS, B, BPLUS, AMINUS, A};
const int BAR = 60;
const int MAXSTUDENT = 100;
I have them being used and called upon in two separate classes, called student.cpp and course.cpp. They are contained in "global.cpp"
here is the header in student.cpp
#include "student.hpp"
#include "global.cpp"
#include <iostream>
using namespace std;
Here is the header in course.cpp
#include "course.hpp"
#include "student.cpp"
#include <iostream>
using namespace std;
No matter what combination of headers, or attempts to split the global variables into the classes they are being used by, i am getting a "redefinition" error. If i uninclude "#student.cpp" in the course.cpp section, i won't get the error, but i need the student.cpp for the course.cpp to work.
I'm way out of my element, would appreciate any help.
Create a file global.h. In that file you can declare your global variables. enum GRADE is not a variable but a type. It is important to remember that you can declare types and variables multiple times, but you can define them only once. So do not define them in the header, just declare them. If you want to use the same global variable across multiple cpp files you must declare them with external linkage.
/* File global.h */
#pragma once
extern const int BAR;
extern const int MAXSTUDENT;
This is an example student.h:
/* File student.h */
#pragma once
enum GRADE {F, D, CMINUS, C, CPLUS, BMINUS, B, BPLUS, AMINUS, A};
class Student
{
public:
Student();
virtual ~Student();
/* put more members here */
};
Here is an example course.h:
/* File course.h */
#pragma once
#include "student.h"
class Course
{
public:
Course();
virtual ~Course();
void addStudent(Student& student);
private:
std:vector<Student*> students;
}
Then you can choose one *.cpp file to define the globals.
For example you put them in student.cpp. Then you can already use them in student.cpp:
/* File student.cpp */
#include "student.h"
const int BAR = 60;
const int MAXSTUDENT = 100;
/* definition of student methods ... for example */
Student::Student()
{ }
Student::~Student()
{ }
In that case you do not include the global.h in the student.cpp file.
Also please do not #include any *.cpp files.
Put the declaration of your student class into student.h, put the definition of methods of the student class into student.cpp.
In the course.cpp just include global.h, course.h. But the student.h is already included via course.h. Then you can also use the global variable in this cpp.
/* file course.cpp */
#include "course.h"
#include "global.h"
/* definition of course methods ... for example */
Course::Course()
{ }
Course::~Course()
{ }
Course::addStudent(Student& student)
{
if(students.size() < MAXSTUDENT) {
// ......
}
}
Hope that helps you.
I'm a first-year college student that doesn't know everything about CS yet, so please bear with my newness to it, and this is my first question on here.
For an assignment, we are making faux version of Pokemon Go to practice using polymorphism in c++, and I'm running into some compiler errors. Here are the three files with just a sample of the code in them:
#ifndef EVENT_H
#define EVENT_H
#include <string>
#include "Trainer.h"
class Event{
protected:
std::string title;
public:
Event();
~Event();
virtual void action(Trainer) = 0;
};
#endif
Trainer.h:
#ifndef TRAINER_H
#define TRAINER_H
#include "Pokemon.h"
class Trainer{
private:
Pokemon* pokemon;
int num_pokemon;
public:
Trainer();
~Trainer();
//include accessors and mutators for private variables
};
#endif
Pokemon.h:
#ifndef POKEMON_H
#define POKEMON_H
#include "Event.h"
#include <string>
class Pokemon : public Event{
protected:
std::string type;
std::string name;
public:
Pokemon();
~Pokemon();
virtual bool catch_pokemon() = 0;
};
#endif
The trainer.h file is a parent class for each pokemon type (eg Rock) which just defines a few virtual functions. The error I'm getting is when I'm compiling all of this and I get something that says:
Pokemon.h : 5:30: error: expected class-name befoer '{' token:
class Pokemon : Event {
Pokemon need to be a derived class to an event, so that an event pointer can point in another Location class can point to either a pokemon, pokestop, or cave for the assignment, and I have been looking online for hours and can't figure out what to do. I would appreciate the help! Let me know if you need more info or something because again, this is my first time posting a question.
You need some forward declarations.
In Event.h, you can put class Trainer; instead of #include "Trainer.h". In Trainer.h, you can put class Pokemon; instead of #include "Pokemon.h".
You will probably need to include the appropriate headers in the corresponding source files in order to actually use the other classes. But by avoiding the includes in the header files, you get out of the circular dependency trouble.
Pokemon.h must continue to #include "Event.h", since you're inheriting Event, which requires a complete definition.
Use forward declaration, to tell classes the type they need to use will be defined later. You can use forward declaration in situations where the size is know, pointers and references are always the same size regardless of the type they point to so use them.
#ifndef EVENT_H
#define EVENT_H
#include <string>
class Trainer;
class Event
{
protected:
std::string title;
public:
Event();
virtual ~Event();
virtual void action(Trainer* const trainer) = 0;
};
#endif
then
#ifndef TRAINER_H
#define TRAINER_H
class Pokemon;
class Trainer
{
private:
Pokemon* const pokemon;
int numPokemon;
public:
Trainer();
~Trainer();
};
#endif
then
#ifndef POKEMON_H
#define POKEMON_H
#include "Event.h"
#include <string>
class Pokemon : public Event
{
protected:
std::string type;
std::string name;
public:
Pokemon();
virtual ~Pokemon();
virtual bool catchPokemon() = 0;
};
#endif
when using polymorphism (virtual functions) you must always make the base class destructor virtual too. It is also nice to make the derived classes destructor virtual as well, but it is not required.
I've been googling and reading about this and didn't come up with an answer yet, maybe someone can help me with this please.
the error I get is: expected class-name before '{' token
Carte_num.h
#ifndef CARTE_NUM_H
#define CARTE_NUM_H
#include <string.h>
#include <iostream>
#include "Carte.h"
using namespace std;
class Partie;
class Carte_num : public Carte
{ //<--------------this is where I get the error
public:
Carte_num(int haut,string typ, char coul [8], int nb_p);
~Carte_num();
protected:
int hauteur;
public:
friend Partie;
};
#endif // CARTE_NUM_H
Carte.h
#ifndef CARTE_H
#define CARTE_H
#include <iostream>
#include <string.h>
#include "Partie.h"
using namespace std;
class Joueur;
class Partie;
class Carte
{
public:
Carte();
Carte( string typ, char coul [8], int nb_p);
~Carte();
protected:
char couleur[8];
int nb_pts;
string type;
public:
//bool action(Partie p);
string definir();
bool est_valable(Partie p);
//int getnb_pts() { return(nb_pts);}
friend class Joueur;
friend class Partie;
};
#endif // CARTE_H
the error I get is: expected class-name before '{' token where I indicated earilier
First, the friend declaration should be
friend class Partie;
Second, you need to include the <string> header, without the trailing .h. That is where std::string is defined.
Third, you could have a circular include dependency, for example if Partie.h includes Carte.h or Carte_num.h. You can fix that by removing #include "Partie.h" from Carte.h (you may need to include it in Carte's implementation file).
Another possibility is that you have a missing ; after your class Carte declaration in Carte.h.
Your friend declaration is incorrect.
See the correct format:
class Carte_num : public Carte
{
// ...
friend class Partie;
};
I have this annoying error in my program.
"Vehicle" is the Base class.
"Bicycle" extends this class.
#ifndef BICYCLE_H
#define BICYCLE_H
#include "Vehicle.h"
#include <string>
#include <iostream>
using namespace std;
//Template class which is derived from Vehicle
template<typename T>
class Bicycle: public Vehicle
{
public:
Bicycle();
Bicycle(int, int, string, int);
~Bicycle();
//Redefined functions inherited from Vehicle
void move(int, int); // move to the requested x, y location divided by 2
void set_capacity(int); // set the capacity value; can't be larger than 2
};
Above is the Bicycle.h file (I do not have .cpp file for this class)
#ifndef VEHICLE_H
#define VEHICLE_H
#include "PassengerException.h"
#include <string>
#include <iostream>
using namespace std;
//ADD LINE HERE TO MAKE IT A TEMPLATE CLASS
template<typename T>
class Vehicle
{
public:
Vehicle(); //default contstructor
Vehicle(int, int, string, int); // set the x, y, name, and capacity
virtual ~Vehicle(); //destructor; should this be virtual or not???
//Inheritance - question #1; create these functions here and in Bicycle class
string get_name(); // get the name of the vehicle
void set_name(string); //set the name of the vehicle
void print(); // std print function (GIVEN TO YOU)
//Polymorphism - question #2
virtual void move(int, int); // move to the requested x, y location
virtual void set_capacity(int); // set the capacity value
//Operator overloading - question #3
Vehicle<T> operator+(Vehicle<T> &secondVehicle) const;
//Exceptions - question #4
T get_passenger(int) throw(PassengerException); // get the passenger at the specified index
void add_passenger(T) throw(PassengerException); // add passenger and the current passenger index
void remove_passenger() throw(PassengerException); // remove a passenger using current passenger index
protected:
int x_pos;
int y_pos;
string name;
int capacity;
T *passengers;
int current_passenger;
};
Above is the Vehicle.h file. I do not have .cpp for this either.
Also, what do the ifndef define endif mean? Do I have to use those? Are they required?
And, do their names have to be formatted like that?
class Bicycle: public Vehicle
Vehicle is a template, so you need this:
class Bicycle: public Vehicle<T>
The #ifndef and #define and #endif are called header guards and are used to prevent your header file from being included more than once, causing things (classes) to be declared more than once.
The ifndef define and endif are necessary for the actual base files, i.e. the c++ files themselves. Yes they are required, if you plan to use those functions and variables accordingly. Yes, their names have to be formatted that way, that's the way directives or in some cases flags must be formatted.
You have to put #endif at the end of your header files. These are so called define guards to prevent multiple inclusion of header files. See more at Include guard.
Hi am having problems compiling some code, I have a situation where A depends and B depends on A. I have put forward declarations but I keep getting the problems.
In file included from src/MemoWriteContext.h:7:0,
from src/MemoWriteContext.cpp:1:
src/MemoContext.h:29:20: error: field ‘memoWriteContext’ has incomplete type
MemoContext.h
#ifndef MEMOCONTEXT_H_
#define MEMOCONTEXT_H_
#include "sqlite/SqliteDb.h"
#include "Context.h"
#include "MemoWriteContext.h"
#include <string>
#include <memory>
#include <map>
namespace bbs
{
class MemoWriteContext;
class MemoContext : public Context
{
public:
//'structors
MemoContext(const std::map<std::string, std::shared_ptr<Context> > &_contexts,
sqlitecpp::SqliteDb &_sqliteDb);
~MemoContext();
protected:
//when called write the data back to the user
void performAction(const std::string &data, std::shared_ptr<UserAgent> agent);
private:
MemoWriteContext memoWriteContext;
}; //class memocontext
}
#endif // MEMOCONTEXT_H_
MemoWriteContext.h
#ifndef MEMOWRITECONTEXT_H_
#define MEMOWRITECONTEXT_H_
#include "Context.h"
#include "sqlite/SqliteDb.h"
#include "sqlite/PreparedStmt.h"
#include "MemoContext.h"
#include <string>
#include <memory>
#include <map>
namespace bbs
{
class MemoContext; //forward decl
class MemoWriteContext : public Context
{
public:
//'structors
MemoWriteContext(const std::map<std::string, std::shared_ptr<Context> > &_contexts,
MemoContext &_memoContext, sqlitecpp::SqliteDb &_sqliteDb);
~MemoWriteContext();
protected:
//when called write the data back to the user
virtual void performAction(const std::string &data, std::shared_ptr<UserAgent> agent);
virtual void onReceiveUserAgent(std::shared_ptr<UserAgent> agent);
private:
MemoContext &memoContext; //parent;
sqlitecpp::SqliteDb &sqliteDb;
sqlitecpp::PreparedStmt writeMemoStmt;
sqlitecpp::PreparedStmt findAgentIdStmt;
};
enum class MemoWriteState : char
{
USERNAME=0,
MESSAGE,
CONFIRM
};
class MemoWriteAgentData : public ContextAgentData
{
public:
MemoWriteState state;
int userId;
std::string message;
}; //class Memo Write Agent data
}
#endif // MEMOWRITECONTEXT_H_
Full source here.
I think your only problem is that MemoWriteContext.h has #include "MemoContext.h". The context only requires a reference which can use the forward declaration. But if you happen to include MemoWriteContext.h first it will then bring in MemoContext.h before it actually declares class MemoWriteContext. That will then use the forward declaration of class MemoWriteContext and fail. You can even see the ordering in your error message.
Just remove that #include or at least reverse the order of the includes in MemoWriteContext.cpp (since each .h including the other effectively reverses them back).
This:
class MemoWriteContext;
Is a forward declaration. It's an "incomplete type", and therefore cannot be instantiated.
The reason is that a C++ compiler must know the size of any type that has to be instantiated. Incomplete types have no size.
By the way, you can do this:
MemoWriteContext * ptr;
Because you actually declare a pointer, and pointers have a known size.
If you want to avoid dynamic allocations, then you'll have to fully declare the type by including MemoWriteContext.h and removing the forward declaration.