C2061 - Circular dependency - c++

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)

Related

2 classes with the same name within namespaces

I have gone back to learning C++ doing some old university courses and I am now currently learning parametric polymorphism as well as creating my own namespaces.
The exercise states that I have to make a namespace called "Federation" which has a class called "Ship" that takes values and one default value that never changes.
inside the federation namespace there is also a "Starfleet" namespace in which we also have a "Ship" class, the only difference is that the default value stated before can be specified by the user.
Here is the code:
Federation.hpp
#include <iostream>
#include <string>
#include <cstring>
namespace Federation
{
namespace Starfleet
{
class Ship
{
public:
Ship(int length, int width, std::string name, short maxWarp);
~Ship();
private:
int _length;
int _width;
std::string _name;
short _maxWarp;
};
};
class Ship
{
public:
Ship(int length, int width, std::string name);
~Ship();
private:
int _length;
int _width;
std::string _name;
}
};
Federation.cpp
#include "Federation.hpp"
using namespac std;
Federation::Starfleet::Ship::Ship(int length, int width, string name, short maxWarp): _length(length), _width(width), _name(name), _maxWarp(maxWarp)
{
cout << "Starfleet Ship Created." << endl;
}
Federation::Starfleet::Ship::~Ship()
{
}
Federation::Ship::Ship(int length, int width, string name, int speed = 1): _length(length), _width(width), _name(name)
{
cout << "Regular Ship Created"
}
Federation::Ship::~Ship()
{
}
main.cpp
#include "Federation.hpp"
int main(int ac, char **av)
{
Federation::Starfleet::Ship mainShip(10, 10, "Starfleet Ship", 20);
Federation::Ship smallShip(5, 5, "Small Ship");
}
When compiling I get this Error: "prototye for Federation::Ship::Ship(int, int, std::__cxx11::string, int) does not match any class in Federation::Ship"
I am totally lost as to what this means, when I look at my functions on my hpp file all of them seem to be correct, so I don't really understand what exactly I'm doing wrong in this case.
This has nothing to do with namespaces. You declare the c'tor with a certain prototype in the header:
Ship(int length, int width, std::string name);
And then randomly add a parameter with a default argument in the implementation file:
Federation::Ship::Ship(int length, int width, string name, int speed = 1)
Argument types are a part of any function or constructor's signature. So you have a declaration and definition mismatch. Declare the extra parameter in the header (along with the default argument).
Ship(int length, int width, string name, int speed = 1);
// and
Federation::Ship::Ship(int length, int width, string name, int speed)

Variable or field declared void C++

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...

No default constructor exists for class c++ [duplicate]

This question already has answers here:
Why does C++ allow us to surround the variable name in parentheses when declaring a variable?
(2 answers)
Closed 5 years ago.
Hello,
I'm trying to instantiate an anonymous object with a std::string variable 'name'. But intellisenen gives me error saying
E0291 no default constructor exists for class "Player" GoldGame e:\C++ Projects\Hello World\GoldGame\GoldGame.cpp 17
I have provided a constructor which can just take a std::string variable since other parameters are provided with default value.
Can you guys shed some light on this?
What confuses me even more is that when I change
Player(name);
to
Player a(name);
or to
Player("test");
then intellisense becomes totally fine with those.
GoldGame.cpp
#include "stdafx.h"
#include "Creature.h"
#include "Player.h"
#include <iostream>
#include <string>
int main()
{
std::cout << "Enter your name: ";
std::string name;
std::cin >> name;
Player(name);
return 0;
}
Creature.h
#pragma once
#include <string>
class Creature
{
public:
Creature(const std::string &name, const char symbol, const int health, const int damage, const int gold);
~Creature();
//getters
const std::string& getName() { return m_name; }
const char getSymbol() { return m_symbol; }
const int getHealth() { return m_health; }
const int getDamage() { return m_damage; }
const int getGold() { return m_gold; }
//health, gold and dead
void reduceHealth(const int healthMinus);
void addGold(const int gold);
bool isDead();
private:
std::string m_name;
char m_symbol;
int m_health;
int m_damage;
int m_gold;
};
Creature.cpp
#include "stdafx.h"
#include "Creature.h"
Creature::Creature(const std::string & name, const char symbol, const int health, const int damage, const int gold)
:m_name(name), m_symbol(symbol), m_health(health), m_damage(damage), m_gold(gold)
{
}
Creature::~Creature()
{
}
void Creature::reduceHealth(const int healthMinus)
{
m_health -= healthMinus;
}
void Creature::addGold(const int gold)
{
m_gold += gold;
}
bool Creature::isDead()
{
if (m_health>0)
{
return true;
}
else
{
return false;
}
}
Player.h
#pragma once
#include "Creature.h"
#include <string>
class Player :
public Creature
{
public:
Player(const std::string &name, const char symbol='#', const int health=10, const int damage=1, const int gold=0);
~Player();
const int getLevel() { return m_level; }
void levelUp();
bool hasWon();
private:
int m_level;
};
Player.cpp
#include "stdafx.h"
#include "Player.h"
Player::Player(const std::string & name, const char symbol, const int health, const int damage, const int gold)
:Creature(name,symbol,health,damage,gold)
{
}
Player::~Player()
{
}
void Player::levelUp()
{
++m_level;
}
bool Player::hasWon()
{
if (m_level>=20)
{
return true;
}
else
{
return false;
}
}
Player(name); does not do what you think it does. It declares a new variable name of type Player and calls a default constructor. If you want to instantiate an anonymous Player variable then you need to write
(Player(name));
// or
Player{name}; // list initialization since C++11

C++ Request for member, which is of non-class type (when using class template, can't define in the main)

**On my main i can't add a note on my new Object of the Class Trabalho
ass.add_nota(num);
**
There is a error on my compilation.
My "Trabalho.h" code:
#include <string>
#include <vector>
#include <iostream>
//#include "Enunciado.h"
//#include "Pessoa.h"
using namespace std;
class Estudante;
class Enunciado;
template <class T>
class Trabalho{
static int id_auxiliar;
string texto;
int ano;
int id;
vector<float> calif;
T* Enun;
vector<Estudante*> estudantes;
vector<Enunciado*> enunciados;
public:
Trabalho();
Trabalho(string texto, vector<Estudante*> est, T* en, int ano);
~Trabalho();
void set_texto(string texto);
string get_texto();
void add_nota(float nota);
void add_enun(Enunciado* en){Enun = en;};
int get_id(){return id;};
int get_ano() {return ano;};
void reutilizar(int id_enun);
vector<float> get_calif() {return calif;};
vector<Estudante*> get_estudantes() {return estudantes;};
Enunciado* get_enunciado() {return Enun;};
};
#endif
And my main code:
int main(int argc, char const *argv[]) {
int n;
int m;
Pesquisa ah();
float num = 1.1;
Trabalho<Pesquisa> ass();
Trabalho<Pesquisa>* tass = new Trabalho<Pesquisa>();
ass.add_nota(num);
tass->add_nota(num);
#ifndef ENUNCIADO_H_
#define ENUNCIADO_H_
#include "trabalho.h"
#include "Pessoa.h"
#include <string>
using namespace std;
class Enunciado
{
static unsigned int id_auxiliar;
const unsigned int id;
string titulo;
string descricao;
vector<int> anos_utilizados;
static unsigned int max_util;
public:
Enunciado(string titulo, string descricao);
virtual ~Enunciado();
int get_id(){return id;};
void set_titulo(string titulo);
string get_titulo();
void set_descricao(string descricao);
string get_descricao();
vector<int> get_anos_utilizados();
void mod_max_util(int a);
};
class Pesquisa: public Enunciado{
vector<string> ref;
public:
Pesquisa(string tit, string des, vector<string> refe);
};
class Analise: public Enunciado{
vector<string> repositorios;
public:
Analise(string tit, string des, vector<string> repos);
};
class Desenvolvimento: public Enunciado{
public:
Desenvolvimento(string tit, string des);
};
#endif
Both ways when i create a new Trabalho when i define my type (pesquisa is a class type on #include "Enunciado.h".
This is the two erros that appears:
"Description Resource Path Location Type
request for member 'add_nota' in 'ass', which is of non-class type 'Trabalho()' Test.cpp /Trabalho1/src line 42 C/C++ Problem
"
And:
Description Resource Path Location Type
Method 'add_nota' could not be resolved Test.cpp /Trabalho1/src line 42 Semantic Error
Can anyone help?
Thank you !
Your error is in trying to call the default constructor as
Pesquisa ah();
or
Trabalho<Pesquisa> ass();
Unfortunately, C++ is very misleading in this and it would declare your variable ass of type Trabalho<Pesquisa>(), which means "a function of zero arguments returning Trabalho<Pesquisa>" and that's exactly that the compiler error says: a function type is not a class type and as such does not have the member add_nota. Indeed, it does look exactly like a function declaration, if you look at it that way:
int main();
^ ^ ^
type arguments
name
It's a very common mistake, especially for those coming from a Java background. But it can easily catch a C++ programmer off guard as well. More information can be found here or here or here, you can see that the same error message has perplexed a good many people.
If you have a compiler conforming to the C++11 language revision, try replacing all those occurrences by
Trabalho<Pesquisa> ass{};
If not, just leave
Trabalho<Pesquisa> ass;
Unlike in Java, this does not mean that the variable will stay uninitialized. It's the C++ way to call a default (zero-argument) constructor.

exc_bad_access error

I'm writing a program for a homework assignment. The program compiles and runs, but has a bad access error.
This is main.cpp
#include <iostream>
#include <string>
#include "Mammal.h"
#include "Dog.h"
#include "Horse.h"
#include "Pig.h"
#include "Cat.h"
using namespace std;
//Seed for ease of grading
const int SEED=100;
const int NUM_ANIMALS=5;
const int WEIGHT_LIMIT=150;
void MammalAssignment(const Mammal * new_Mammal, int choice, string newName);
void UserChoice(const Mammal * new_Mammal);
void ListAnimal(const Mammal *new_Mammal);
int main()
{
string newName, newWeight;
srand(SEED);
Mammal *new_Mammal[NUM_ANIMALS];
UserChoice(*new_Mammal);
for(int i=0; i<NUM_ANIMALS; i++)
ListAnimal(new_Mammal[i]);
//Program pauses for user input to continue
char exit_char;
cout<<"\nPress any key and <enter> to exit\n";
cin>>exit_char;
return 0;
}
void UserChoice(const Mammal * new_Mammal)
{
int choice;
bool choiceGood;
string newName;
for(int i=0;i<NUM_ANIMALS; i++){
choiceGood=false;
while(choiceGood==false)
{
cout<<"-Please choose a number 1-4 for the corresponding animal-\n"
<<"1-Dog\n2-Horse\n3-Pig\n4-Cat\n";
cin>>choice; //User choice
if(choice<=0 || choice >=5){
cout<<"Your choice is invalid\n\n";
continue;
}
choiceGood=true;
} //While loop
cout<<"\nPlease enter a name for the animal you have chosen(Ex. Fido).\n";
cin>>newName;
MammalAssignment(&new_Mammal[i], choice, newName);
} //For loop
}
void MammalAssignment(const Mammal * new_Mammal, int choice, string newName)
{
if(choice==1){
Dog newDog(rand()%(WEIGHT_LIMIT+1), newName);
new_Mammal=&newDog;
}
else if(choice==2){
Horse newHorse(rand()%(WEIGHT_LIMIT+1), newName);
new_Mammal=&newHorse;
}
else if(choice==3){
Pig newPig(rand()%(WEIGHT_LIMIT+1), newName);
new_Mammal=&newPig;
}
else if(choice==4){
Cat newCat(rand()%(WEIGHT_LIMIT+1), newName);
new_Mammal=&newCat;
}
}
void ListAnimal(const Mammal *new_Mammal)
{
cout<<"-------------------------\nName:"
<<new_Mammal->GetName()<<"\nWeight: "
<<new_Mammal->GetWeight();
}
Mammal.h
#ifndef MAMMAL_H
#define MAMMAL_H
using namespace std;
class Mammal
{
public:
Mammal(); //Default constructor
Mammal( int newWeight); //Parameterized constructor
void SetWeight(int newWeight);
virtual string GetName() const;
int GetWeight() const;
//virtual function to be defined by derived animal classes
virtual void Speak() const;
private:
int weight;
};
#endif
Mammal.cpp
#include <iostream>
#include <string>
#include "Mammal.h"
using namespace std;
Mammal::Mammal()
{
SetWeight(0);
cout<<"\nInvoking default Mammal Constructor\n";
}
Mammal::Mammal( int newWeight)
{
SetWeight(newWeight);
cout<<"\nInvoking parameterized Mammal Constructor\n";
}
void Mammal::SetWeight(int newWeight)
{
weight=newWeight;
}
int Mammal::GetWeight() const
{
return weight;
}
string Mammal::GetName() const
{}
void Mammal::Speak() const
{
cout<<"\nLadies and gentlemen, the mammal speaks...\n";
}
Dog.h
#ifndef DOG_H
#define DOG_H
#include "Mammal.h"
using namespace std;
class Dog: public Mammal
{
public:
Dog(); //Default constructor
Dog(const int& newWeight,const string& newName); //Parameterized constructor
void SetName(string newName);
string GetName() const;
//mammal virtual function
virtual void Speak() const;
private:
string name;
};
#endif
Dog.cpp
#include <iostream>
#include <string>
#include "Dog.h"
using namespace std;
//Default constructor
Dog::Dog()
{
cout<<"\nInvoking default Dog constructor\n";
}
//Parameterized constructor
Dog::Dog( const int& newWeight,const string& newName):Mammal(newWeight)
{
SetName(newName);
cout<<"\nInvoking parameterized Dog constructor.\n";
}
void Dog::SetName(string newName)
{
name=newName;
}
string Dog::GetName() const
{
return name;
}
//mammal virtual function
void Dog::Speak() const
{
Mammal::Speak();
cout<<"\nWoof!\n";
}
The other derived classes(horse, pig, and cat) are all identical to Dog. I'm getting a Exc_Bad_Access error when ListAnimals() gets to GetWeight(). As far as I can tell it's returning the right file type. Any help would be awesome
Your MammalAssignment function is returning a pointer to a local variable. Once the function returns, that memory (which was on the stack) is gone and you will crash when you access it as an object of the relevant mammal type.
You need to return a pointer to memory allocated using operator new, or possibly just an object instead of a pointer, assuming suitable copy semantics are implemented in your Mammal classes.
A revision (or initial self-education?)of memory management in C++ would be in order before you go any further. See also smart pointers, to avoid new/delete where possible and make your life easier.
Mammal *new_Mammal[NUM_ANIMALS];
You need to allocate memory using new !
Mammal *new_Mammal = new Mammal[NUM_ANIMALS];
Also I think your UserChoice function should take the pointer as a reference and not as a const value to be able to change the actual content.