I am making a school assignment, but I am getting a strange error. I have tried to google it, but nothing helped.
So I have a file called main.cpp. Within this file I have some includes and code.
This:
#include <iostream>
#include <stdexcept>
#include <string>
using namespace std;
#include "RentalAdministration.h"
#include "Limousine.h"
#include "Sedan.h"
void addTestDataToAdministration(RentalAdministration* administration)
{
string licencePlates[] = {"SD-001", "SD-002", "SD-003", "SD-004", "LM-001", "LM-002"};
for (int i = 0; i < 4; i++)
{
Car* sedan = new Sedan("BMW", "535d", 2012 + i, licencePlates[i], false);
administration->Add(sedan);
}
for (int i = 4; i < 6; i++)
{
Car* limousine = new Limousine("Rolls Roys", "Phantom Extended Wheelbase", 2015, licencePlates[i], true);
administration->Add(limousine);
}
}
int main( void )
{
RentalAdministration administration;
addTestDataToAdministration(&administration);
}
So the compiler tells me that the variable: "RentalAdministration administration" does not exist.
So if we have look in my rentaladministration header. We see this:
#ifndef RENTALADMINISTRATION_H
#define RENTALADMINISTRATION_H
#include <vector>
#include "car.h"
class RentalAdministration
{
private:
std::vector<Car*> Cars;
Car* FindCar(std::string licencePlate);
Car* FindCarWithException(std::string licencePlate);
public:
std::vector<Car*> GetCars() const {return Cars;}
bool Add(Car* car);
bool RentCar(std::string licencePlate);
double ReturnCar(std::string licencePlate, int kilometers);
void CleanCar(std::string licencePlate);
RentalAdministration();
~RentalAdministration();
};
#endif
This is the exact error:
src/main.cpp:18:34: error: variable or field ‘addTestDataToAdministration’ declared void
void addTestDataToAdministration(RentalAdministration* administration)
^
src/main.cpp:18:34: error: ‘RentalAdministration’ was not declared in this scope
src/main.cpp:18:56: error: ‘administration’ was not declared in this scope
void addTestDataToAdministration(RentalAdministration* administration)
Help will be appreciated!
Edit:
I am getting warnings in sublime for the Sedan and Limousine headers. Something that has to do with some static constants. I think it was called a GNU extension. Maybe it has something to do with it.
Even when I comment the call of that function out. I get the same error.
I am calling that function nowhere else.
Some people say that the cause might be in these headers:
#ifndef LIMOUSINE_H
#define LIMOUSINE_H
#include "Car.h"
//c
class Limousine : public Car
{
private:
bool needsCleaning;
bool hasMiniBar;
static const double priceperkm = 2.5;
public:
double Return(int kilometers);
void Clean();
bool GetHasMiniBar() const { return hasMiniBar;}
void SetHasMiniBar(bool value) {hasMiniBar = value;}
Limousine(std::string manufacturer, std::string model, int buildYear, std::string licencePlate, bool hasminiBar);
~Limousine();
};
#endif
2:
#ifndef SEDAN_H
#define SEDAN_H
#include "Car.h"
//c
class Sedan : public Car
{
private:
int lastCleanedAtKm;
bool hasTowBar;
bool needsCleaning;
static const double priceperKm = 0.29;
public:
void Clean();
int GetLastCleanedAtKm() const {return lastCleanedAtKm;}
void SetLastCleanedAtKm(bool value){ lastCleanedAtKm = value;}
bool GetHasTowBar() const {return hasTowBar;}
void SetHasTowBar(bool value) {hasTowBar = value;}
bool GetNeedsCleaning() const {return needsCleaning;}
void SetNeedsCleaning(bool value){needsCleaning = value;}
Sedan(std::string manufacturer, std::string model, int buildYear, std::string licencePlate, bool hastowBar);
~Sedan();
};
#endif
class Limousine : public Car
{
private:
static const double priceperkm = 2.5;
...
}
Remove the static and declare the member simply as const double, example:
class Limousine : public Car
{
private:
const double priceperkm = 2.5;
...
}
The error message ‘RentalAdministration’ was not declared in this scope indicates that the right header file for RentalAdministration was not included. Check the file names to make sure class declaration for RentalAdministration is in the right file.
Restarting the terminal has somehow solved this error. I got another error this time, which I solved already. I missed the destructor. It stood in the header file, but not in the cpp file.
Buggy terminals...
Related
I am preparing a program with several classes, which have to exchange data between each other subsequently in the code. This results in inclusion of classes in each other headers. I have encountered a problem when it came to passing a vector of "Gas" objects to the "Thermal" class method and afterwards trying to pass a changed "Thermal" object to the "Gas" class method. I have tried forward including of the classes in each other header files, but with a miserable result. Maybe I did something wrong with that. Possibly a declaration of a pointers between class objects would solve a problem? I have tired this, but unfortunately I may lack of experience with pointers, as I failed as well.
Notice - When I comment out the #include "Thermal.h" from the "Gas" class, the code compiles successfully. However, then the diffusion method has to be commented out as well.
The compilier returns, as follows:
./src/Thermal.h:86:76: error: template argument 2 is invalid
./src/solution.cpp: In function 'void solution(const Ref::Reformer&,
const std::vector<Ref::Segment>&, std::ofstream*, std::ofstream*, std::ofstream*)':
./src/solution.cpp:92:40: error: no matching function for call to 'Ref::Thermal::
conduction(const Ref::Reformer&, Ref::Grid&, std::vector<Ref::Gas>&, Ref::Velocity&)'
T.conduction(reactor, grid, gases, vel);
^
In file included from ./src/Gas.h:20:0,
from ./src/solution.cpp:16:
./src/Thermal.h:86:8: note: candidate: void Ref::Thermal::conduction(const Ref::Reformer&,
const Ref::Grid&, const int&, const Ref::Velocity&)
void conduction(const Reformer& RE, const Grid& GD, const std::vector<Gas>& GAS,
const Velocity& VE);
^
./src/Thermal.h:86:8: note: no known conversion for argument
3 from 'std::vector<Ref::Gas>' to 'const int&'
Here is how I call the methods. Objects of class "Thermal" and "Gas" are created in the same .cpp file and are called subsequently. Their initialization requires construction and passing of a "Grid" class object, which is done in the same file as well.
Objects creation:
Grid grid(0.3, 0.052);
grid.setNX(90);
grid.setNR(15);
Thermal T(grid);
for(i = 0; i < 6; i++){
gases.push_back(Gas(i, grid));
}
Methods' call:
T.conduction(reactor, grid, gases, vel);
for(int i = 0; i < gases.size(); i++){
gases[i].diffusion(reactor, grid, vel, T);
}
Grid class declaration:
#ifndef REFORMING_CODE_REF_GRID_H
#define REFORMING_CODE_REF_GRID_H
#include "../input.h"
namespace Ref{
class Grid{
public:
Grid(const double& x1, const double& r1, const double& x0 = 0., const double& r0 = 0.){
xmin_ = x0;
xmax_ = x1;
rmin_ = r0;
rmax_ = r1;
}
void setNX(const int& nx){ //setting number of elements in the longitudinal direction
NX_ = nx;
ni_ = NX_ - 1;
}
void setNR(const int& nr){ //setting number of elements in the radial direction
NR_ = nr;
nj_ = NR_ - 1;
}
};
}//end of namespace
#endif //REFORMING_CODE_REF_GRID_H
Thermal class declaration:
#ifndef REFORMING_CODE_REF_THERMAL_H
#define REFORMING_CODE_REF_THERMAL_H
#include "../input.h"
#include "Reformer.h"
#include "Grid.h"
#include "Velocity.h"
#include "Gas.h"
namespace Ref{
class Thermal{
public:
Thermal(const Grid& grid){
NX_ = grid.NX();
NR_ = grid.NR();
}
void conduction(const Reformer& RE, const Grid& GD, const std::vector<Gas>& GAS, const Velocity& VE);
private:
int NX_; //quantity of elements in the X direction
int NR_; //quantity of elements in the R direction
std::vector<double> val_; //Temperature value (K)
std::vector<double> val_old_;
std::vector<double> s_; //Thermal source
};
} //end of namespace
#endif //REFORMING_CODE_REF_THERMAL_H
Conduction method definition:
#include "Thermal.h"
namespace Ref{
void Thermal::conduction(const Reformer& RE, const Grid& GD,
const std::vector<Gas>& GAS, const Velocity& VE){}
}
Gas class declaration:
#ifndef REFORMING_CODE_REF_GAS_H
#define REFORMING_CODE_REF_GAS_H
#include "../input.h"
#include "Reformer.h"
#include "Grid.h"
#include "Velocity.h"
#include "Thermal.h"
namespace Ref{
class Gas{
public:
Gas(const int id, const Grid& grid){
id_ = id;
NX_ = grid.NX();
NR_ = grid.NR();
}
void diffusion(const Reformer&, const Grid&, const Velocity&, const Thermal&);
private:
int id_;
int NX_;
int NR_;
};
} //end of namespace
#endif //REFORMING_CODE_REF_GAS_H
Diffusion method definition:
#include "Gas.h"
namespace Ref{
void Gas::diffusion(const Reformer& RE, const Grid& GD,
const Velocity& VE, const Thermal& T){}
} //end of namespace
You could try using forward declarations and moving the #include to the end of the header. ( your file wouldn't be included twice because of the header guards )
Minimal compiling example:
//RecursiveA.h
#ifndef RECURSIVEA_H
#define RECURSIVEA_H
class RecursiveA {
public:
void workOnB(const class RecursiveB &);
};
#include "RecursiveB.h"
#endif // RECURSIVEA_H
//RecursiveB.h
#ifndef RECURSIVEB_H
#define RECURSIVEB_H
class RecursiveB {
public:
void workOnA(const class RecursiveA &);
};
#include "RecursiveA.h"
#endif // RECURSIVEB_H
//RecursiveA.cpp
#include "RecursiveA.h"
void RecursiveA::workOnB(const RecursiveB &b){
}
//RecursiveB.cpp
#include "RecursiveB.h"
void RecursiveB::workOnA(const RecursiveA &a){
}
Object-oriented C++ here.
I'm supposed to code a Microwave object that "heats" a FrozenMeal object.
One method of the Microwave object, called void heatMeal(FrozenMeal), is supposed to take an instance of a FrozenMeal object as a parameter and increase its temperature.
FrozenMeal.h
#include <string>
class FrozenMeal {
public:
FrozenMeal(std::string, int);
void setTemperature(double);
std::string getName() const;
int getVolume() const;
double getCoeffizient() const;
double getTemperature() const;
private:
std::string name;
int volume;
double temperature;
double coeffizient;
};
FrozenMeal.cpp
#include <string>
#include "FrozenMeal.h"
using namespace std;
FrozenMeal::FrozenMeal(string mealName, int mealVolu) {
name = mealName;
volume = mealVolu;
temperature = -18;
coeffizient = 0.24;
}
void FrozenMeal::setTemperature(double mealTemp) { temperature = mealTemp; }
string FrozenMeal::getName() const { return name; }
int FrozenMeal::getVolume() const { return volume; }
double FrozenMeal::getCoeffizient() const { return coeffizient; }
double FrozenMeal::getTemperature() const { return temperature; }
Microwave.h
#include "FrozenMeal.h"
class Microwave {
public:
Microwave();
void morePower();
void lessPower();
void setPeriod(double);
void heatMeal(FrozenMeal); // <----------------------------
int getPower() const;
double getPeriod() const;
private:
int power;
double period;
};
Microwave.cpp
#include "Microwave.h"
using namespace std;
Microwave::Microwave() {}
void Microwave::morePower() { if (power < 1000) power += 200; }
void Microwave::lessPower() { if (power > 200) power -= 200; }
void Microwave::setPeriod(double sessionPeri) { period = sessionPeri; }
void Microwave::heatMeal(FrozenMeal mealInst) {
mealInst.setTemperature(80); //example
}
int Microwave::getPower() const { return power; }
double Microwave::getPeriod() const { return period; }
Now, my problem is that my compiler says that the file FrozenMeal.h apparently redefines the object type of FrozenMeal, even though that should be the job of the FrozenMeal.cpp file, and compiling is unsuccessful.
I tried including FrozenMeal.h to Microwave.cpp but that resulted in even more compiler errors.
I feel like I'm doing something horribly wrong here.
Add include guards to your header files so its contents doesn't get included more than once:
FrozenMeal.h:
#ifndef FROZENMEAL_H_INCLUDED
#define FROZENMEAL_H_INCLUDED
// your code ...
#endif /* FROZENMEAL_H_INCLUDED */
Microwave.h:
#ifndef MICROWAVE_H_INCLUDED
#define MICROWAVE_H_INCLUDED
// your code ...
#endif /* MICROWAVE_H_INCLUDED */
Also, you never initialize int Microwave::power and double Microwave::period so you will read and write garbage values in Microwave::morePower() and Microwave::lessPower()
As suggested in the comments, you want to take the parameter of Microwave::heatMeal() by reference so the function can modify the passed object:
void Microwave::heatMeal(FrozenMeal &mealInst)
// ^
my program basically depends on setters to initialize the data in my object instances but I want to remove them and have constructors in place of the setters, Is there a way I can do this or can anybody provide me a reference?
Instantiate object
//Using SDL and standard IO
#include <SDL.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <iomanip>
#include <archer.hpp>
#include <ctime>
#include <ArmouredArcher.hpp>
#include <RNGI.hpp>
using namespace std; //Declaring use of namespace std
void instantiateMuskateer();
int main(int argc, char* argv[])
{
//init muskateer object
instantiateMuskateer();
system("pause");
return 0;
}
Instantiation, Activity and destruction
void instantiateMuskateer()
{
Archer* Muskateer = new Archer();
Muskateer->setName("Brett");
delete Muskateer;
}
.hpp file
#ifndef _Archer_
#define _Archer_
#include <string>
class Archer
{
public:
inline Archer() :
name(""),
healthpoints(0),
baseDamage(0),
range(0)
{ ; } //All Member varials are in a known state
inline Archer(std::string name, int healthpoints, int baseDamage, int range) :
name(name),
healthpoints(healthpoints),
baseDamage(baseDamage),
range(range) //All member variables are in a known state
{
;
}
inline ~Archer() { ; } // empty destructor
inline std::string getName() { return name; }
inline void setName(std::string name) { this->name = name; }
inline int getHealthPoints() { return healthpoints; }
inline void setHealthPoints(int healthpoints) { this->healthpoints = healthpoints; }
inline int getBaseDamage() { return baseDamage; }
inline void setBaseDamage(int baseDamage) { this->baseDamage = baseDamage; }
inline int getRange() { return range; }
inline void setRange(int range) { this->range = range; }
/*std::string getName(); //getter for name
void setName(std::string name); //Set the name
int getHealthPoints();
void setHealthPoints(int healthpoints);
int getBaseDamage();
void setBaseDamage(int baseDamage);
int getRange();
void setRange(int range); */
protected:
private:
// copy constructor
Archer(const Archer& other) = delete;
// overload assignment operator
Archer& operator=(const Archer& other) = delete;
std::string name;
int healthpoints;
int baseDamage;
int range;
};
#endif
In your example, it is really simple, you just have to take the parameters you need in your constructor:
Archer(std::string n) :
name(n),
healthpoints(0),
baseDamage(0),
range(0)
{} //All Member varials are in a known state
And then you can simply do that:
void instantiateMuskateer()
{
Archer* Muskateer = new Archer("Brett");
delete Muskateer;
}
A few comments not related, but to improve your code. Writing inline is useless when you declare and implement your functions inside your class, the inline is implied. Also, if your destructor does nothing, you should not define it or use = default, that way you can enable some optimizations from the compiler.
Also, in your previous function i see no need to allocate the object on the heap, it is again a loss of performance and a source of error (such as forgetting to delete the object), allocate it on the stack:
void instantiateMuskateer()
{
Archer Muskateer("Brett");
// do your things
}
Or use a unique_ptr.
How to avoid circular dependency on these code:
Mechanic.cpp:
#include "stdafx.h"
#include "Characters.h"
#include "Monsters.h"
using namespace characters;
using namespace monsters;
using namespace std;
void character::character_atack(character const cha, monster &monst)
{
if (cha.dexterity + k(20) >= monst.defense)
monst.health = monst.health - cha.strength;
}
int k(int const max)
{
return (rand() % max);
}
void monster::monster_atack(character &cha, monster const monst)
{
if (monst.atack + k(20) >= cha.dexterity)
cha.health = cha.health - monst.damage;
}
Monsters.h:
#include <iostream>
#include <string>
namespace monsters
{
using namespace std;
class monster{
protected:
string name;
public:
int atack;
int damage;
int health;
int defense;
monster(int atk, int dmg, int hp, int def) : atack(atk), damage(dmg),
health(hp), defense(def) {}
~monster();
void monster_atack(character &cha, monster const monst);
};
class greenskins:monster{
greenskins(int atk, int dmg, int hp, int def) : monster(atk, dmg, hp, def) {}
};
}
Characters.h:
#include <iostream>
#include <string>
#include <vector>
namespace characters
{
using namespace std;
class character{
protected:
int level;
int experience;
string name;
public:
int health;
int strength;
int intelligence;
int dexterity;
struct position{
int x;
int y;
}pos;
character(int str, int in, int dex) : strength(str), intelligence(in),
dexterity(dex), level(1), experience(0) {
cout << "What's your name?" << endl;
cin >> name; }
~character();
void info_character();
void character_atack(character const cha, monster &monst);
};
}
The compilator gives me errors like this:
Error 1 error C2061: syntax error : identifier 'monster'
or
Error 9 error C2511: 'void monsters::monster::monster_atack(characters::character &,const monsters::monster)' : overloaded member function not found in 'monsters::monster'
The issue is that character has a function that takes a monster& and monster has a function that takes a character&, but you don't declare the other class in either case. Thankfully, since you just pass the classes as arguments in both places (as opposed to having them be members or something), it is sufficient to forward-declare both classes in both places:
// in character.h
namespace monsters {
class monster; // just fwd-declare
}
namespace characters {
class character {
// as before
};
}
And similar in the other file.
[update] Also, you're just referencing monster inside of class character in the header file, you need to qualify it as monsters::monster.
The first error comes from the following line in Characters.h
void character_atack(character const cha, monster &monst);
You include Characters.h into your .cpp file before you include the Monsters.h and thus the type monster is not yet known. To fix this, change your Characters.h to look like this:
... //includes
namespace monsters {
class monster;
}
namespace characters {
class character {
... //class definition
}
}
The second error is a not matching signature. You are declaring following method:
void monster_atack(character &cha, monster const monst)
but defining
void monster::monster_atack(character &cha, const monster monst)
At least that is what the compiler said.
I would suggest to change the signature to:
void monster_atack(character &cha, const monster& monst)
to prevent needless copy operations. (depending on optimization of course)
I am trying to understand a few examples of pragma and header compilation with include guards
I am not asking about the difference between them. I am asking specifically if based on the example I provided that I am following, am I illustrating it correct in my class?
I can not tell if its working or not when I run my program.
In the examples they show this,
#pragma once
#if !defined(x_header_included)
#define x_header_included
class X { … };
#endif
Which in my c++ ignorance I have translated to this,
#include <iostream>
#pragma once
#if !defined(my_headers)
#define my_headers
#include "npc.h"
#include "pc.h"
#include "health.h"
class game {
private:
npc n;
pc p;
health h;
public:
game(const npc& init_n, const pc& init_p, const health& init_h):
n(init_n),
p(init_p),
h(init_h)
{}
game(std::string gen, std::string abil, bool use, int lvl, int h, int arm) :
n(gen, abil),
p(use, lvl),
h(h, arm)
{
}
friend std::ostream& operator<<(std::ostream& s, const game& g) {
g.n.output(s);
g.p.output(s);
g.h.output(s);
return s;
}
npc get_n() { return n; }
pc get_p() { return p; }
health get_h() { return h; }
void set_n(npc init_n) { n = init_n; }
void set_p(pc init_p) { p = init_p ; }
void set_h(health init_h) { h = init_h; }
};
#endif
Is that all I do or am I missing something? Does anything else need to be added to the .cpp files from here?
The class I am showing is the composite top level class included in my main.cpp and my game.cpp file.