Error using Qt Creator:"multiple definition" "first defined here" - c++

I have a problem. In my Qt project I'm having an error. Tt says:
multiple definition of estructura
I think it is because I'm using too many "#includes", but I don't know how to fix it.
This is my program:
Struct.h
#ifndef STRUCT_H
#define STRUCT_H
#include <stdio.h>
#include <string>
struct Circulo{
std::string nombre;
int capacidad;
int statusMujer[4];
int hijos[4];
};
struct Circulo estructura[30];
#endif // STRUCT_H
Logica.h
#ifndef LOGICA_H
#define LOGICA_H
#include <iostream>
void madresStatusCodificados(std::string , int , int[]);
void ListadoDeCirculos(int, int , std::string []);
std::string CirculoMayorCapacidad(int );
int NinnosEnCirculosconStatus(int , int );
void Listado(int);
#endif // LOGICA_H
interfaz.cpp
#include <Interfaz/Interfaz.h>
#include <Logica/Defecto.h>
#include <Interfaz/Menu.h>
#include <Logica/Struct.h>
#include <iostream>
using namespace std;
void Principal(){
cin>>estructura[i].statusMujer[3];
cout<<"Escriba la cantidad de hijos con madres desconocidas"<<endl;
cin>>estructura[i].hijos[3];
i++;
}else{
break;
}
}
}
Logica.cpp
#include <iostream>
using namespace std;
//#include <Logica/Logica.h>
#include <Logica/Struct.h>
void madresStatusCodificados(string t, int h , int k[]){
for(int i=0;i<h;i++){
if(estructura[i].nombre==t){
k[0]=estructura[i].statusMujer[0];
k[1]=estructura[i].statusMujer[1];
k[2]=estructura[i].statusMujer[2];
k[3]=estructura[i].statusMujer[3];
}
}
}
void ListadoDeCirculos(int g,int u,string h[]){
for(int i=0;i<u;i++){
if(estructura[i].statusMujer[g-1]!=0)
h[i]=estructura[i].nombre;
}
}
string CirculoMayorCapacidad(int k){
int n=-1;
string l;
for(int i=0;i<k;i++){
if(estructura[i].capacidad>n){
n=estructura[i].capacidad;
l=estructura[i].nombre;
}
}
return l;
}
int NinnosEnCirculosconStatus(int a,int b){
int h=0;
for(int i=0;i<b;i++){
h=h+estructura[i].hijos[a-1];
}
return h;
}
void Listado(int y){
for(int i=0;i<y;i++){
cout<<"NOMBRE DEL CIRCULO CAPACIDAD Madres solteras Madres trabajadoras Madres caso social Madres desconocidas "<<endl;
cout<<estructura[i].nombre<<""<<estructura[i].capacidad<<estructura[i].statusMujer[0]<<estructura[i].statusMujer[1]<<estructura[i].statusMujer[2]<<estructura[i].statusMujer[3]<<endl;
}
}
I am getting this error:
Errors

You have defined a variable named "estructura" in several files, the error tells you that it was first defined in Struct.h being called #included in Logica.cpp,
struct Circulo estructura[30];
you have another definition the the file Defecto.h or a file included by Defecto.h

Move the definition of estructura in a cpp file of your choice, then declare it as extern wherever you need it. And you can omit the struct keyword, in c++.
In a struct.cpp file:
#include "Struct.h"
Circulo estructura[30];
In your Logica.cpp and Interfaz.cpp files:
#include "Struct.h"
extern Circulo estructura[30];
Here is a long and detailed explanation of your issue.

Related

Compiling from multiple files gives "undefined reference"

I need to provide a CFG class in a separate file, but I'm unsure how to compile it together with the associated .h and the main program.
I've #includeed the .h file and I've asked for both files at the command line, but I'm not sure why this is wrong for compiling them together.
Thoughts?
CFG.cpp:
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
class CFG
{
public:
string code[25];
char startNT;
//private:
CFG(string inCode[], int stringLen)
{
for (int a = 0; a < stringLen; a++)
{
//cout << inCode[a] << endl;
this->code[a] = inCode[a];
}
for (int a = 0; a < stringLen; a++)
{
cout << this->code[a] << endl;
}
}
char getStartNT()
{
return startNT;
}
void setStartNT(char stNT)
{
startNT = stNT;
}
bool processData(string inString, string wkString)
{
//Our recursive function
return true;
}
void garbage()
{
return;
}
};
CFG.h:
#ifndef _cfg_h_
#define _cfg_h_
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
class CFG
{
public:
string code[25];
char startNT;
CFG(string inCode[], int stringLen);
char getStartNT();
void setStartNT(char stNT);
bool ProcessData(string inString, string wkString);
void garbage();
};
#endif
cfg_entry.cpp:
#include <stdio.h>
#include <iostream>
#include "cfg.h"
using namespace std;
int main()
{
string inArray[5];
inArray[0] = "test0";
inArray[1] = "test1";
inArray[2] = "test2";
inArray[3] = "test3";
inArray[4] = "test4";
CFG * cfg1 = new CFG(inArray, 5);
cfg1->garbage();
return 0;
}
Compile errors:
art#tv:~/Dropbox/Weber/CS 4110/Individual Assignment 2$ g++ -g -std=c++11 -Wall -o cfg_entry cfg.cpp cfg_entry.cpp
/tmp/ccICQEd0.o: In function `main':
/home/art/Dropbox/Weber/CS 4110/Individual Assignment 2/cfg_entry.cpp:15: undefined reference to `CFG::CFG(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >*, int)'
/home/art/Dropbox/Weber/CS 4110/Individual Assignment 2/cfg_entry.cpp:16: undefined reference to `CFG::garbage()'
collect2: error: ld returned 1 exit status
I found my issue. In my case, the header file was defining the class and the .cpp file was re-defining it again, trying to create 2 instances of the CFG class. The .h needed to handle the class declaration and variable instantiation while the .cpp handles only the function definitions.
cfg.h:
#ifndef _cfg_h_
#define _cfg_h_
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
class CFG
{
private:
string code[25];
char startNT;
public:
CFG(string inCode[], int stringLen);
char getStartNT();
void setStartNT(char stNT);
bool processData(string inString, string wkString);
void garbage();
};
#endif
cfg.cpp:
#include <iostream>
#include <stdio.h>
#include <string>
#include "cfg.h"
using namespace std;
CFG::CFG(string inCode[], int stringLen)
{
for (int a = 0; a < stringLen; a++)
{
//cout << inCode[a] << endl;
this->code[a] = inCode[a];
}
for (int a = 0; a < stringLen; a++)
{
cout << this->code[a] << endl;
}
}
char CFG::getStartNT()
{
return startNT;
}
void CFG::setStartNT(char stNT)
{
startNT = stNT;
}
bool CFG::processData(string inString, string wkString)
{
//Our recursive function
return true;
}
void CFG::garbage()
{
return;
}

Undefined Reference Error/ Dynamically Calling Functions

Hi I am working on a program that involves a Main.cpp, Connect4.cpp, and Connect4.h file. When I compile my program I am getting an error in the Main file saying that my playGame function is an undefined reference. I am compiling both files together(main first) I believe something is wrong in the way I am trying to dynamically call the function playGame. Any input would be much appreciated!
Main.cpp
#include <iostream>
#include <array>
#include "Connect4.h"
void playGame();
using namespace std;
int main()
{
Connect4 *ptr;
ptr=new Connect4;
ptr-> playGame();
delete ptr;
}
Connect4.cpp
#include <iostream>
#include <array>
#include "Connect4.h"
char gameBoard[9][7];
int rows;
int columns;
using namespace std;
void playGame()
{
void display();
int selectColumn(bool);
int tokenPlacement(char token, int columns);
bool winOrLose();
cout<<"Welcome to Connect Four.";
for(int i=0; i<rows;++i)
{
for(int j=0; j<columns; ++j)
{
gameBoard[i][j]=' ';
}
}
bool player1Turn=true;
char winner='n';
int column =0;
while(true){
display();
column=selectColumn(player1Turn);
if(player1Turn==true)
{
tokenPlacement('x',column);
player1Turn=false;
}
else
{
tokenPlacement('o', column);
player1Turn=true;
winner= winOrLose();
if(winner!='n')
{
break;
}
}
cout<<"Winner is:"<<winner;
}
Connect4.h
#ifndef CONNECT4_H_
#define CONNECT4_H_
#include
using namespace std;
class Connect4 {
public:
static void playGame();
private:
void display();
int selectColumn(bool);
int tokenPlacement(char, int);
bool winOrLose();
char gameBoard[9][7];
};
#endif /* CONNECT4_H_ */

Virtual keyword seems to be ignored

This is my first "big" C++ project and I am stuck. I am trying to create a simple ASCII roguelike. I have a character class that is inherited by a Player class and a Monster class. The Monster class is inherited by Vampire and Werewolf classes.
In the startGame function of the GameSystem class I submit every element of a Monsters array (that is supposed to be filled with Vampire and Werewolf objects) to the function moveAround. Vampires, Werewolfs, and Monsters all have this function yet only the Monster moveAround function is being accessed. If you notice in the code below I have the virtual keyword provided in the Monster class.
This leads me to think I messed up when I filled the Monster array with the subclasses. I did this in the GameSystem constructor by randomly determining if a particular element of the Monster array was going to be a werewolf or a vampire.
I am using codeblocks and in terms of compiling I have g++ following C++11.
GameSystem.cpp
#include <iostream>
#include <string>
#include "GameSystem.h"
#include "Map.h"
#include "Player.h"
#include "Werewolf.h"
#include "Vampire.h"
#include "conio.h"
#include <cstdio>
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <time.h>
GameSystem::GameSystem(string mapName){
srand (time(NULL));
_map.load(mapName);
_map.obtainSpawningLocations(_player.getToken(),_player);
Werewolf werewolf;
Vampire vampire;
for(int i = 0; i < 5; i++){
_spawnValue = rand() % 2; //We generate either 1 or 2
if(_spawnValue==1){
_theMonsters[i] = werewolf;
cout<<"Werewolf"<<endl;
}
else{
_theMonsters[i] = vampire;
cout<<"Vampire"<<endl;
}
_map.obtainSpawningLocations(_theMonsters[i].getToken(),_theMonsters[i]);
}
}
void GameSystem::startGame(){
bool isOver = false;
while(isOver!=true){
_map.print();
movePlayer();
for(int i = 0; i <5; i++){
_theMonsters[i].moveAround(); //prints out Monster.moveAround()
//I need it to print out Vampire.moveAround() and //Werewolf.moveAround
}
}
}
void GameSystem::movePlayer(){
char input;
input = getch();
string clearScreenString(100,'\n'); //Prints out a newLine char 100 times
cout << clearScreenString;
_map.checkMovement(input, _player);
}
char GameSystem::getch(){
char buf=0;
struct termios old={0};
fflush(stdout);
if(tcgetattr(0, &old)<0)
{perror("tcsetattr()");}
old.c_lflag&=~ICANON;
old.c_lflag&=~ECHO;
old.c_cc[VMIN]=1;
old.c_cc[VTIME]=0;
if(tcsetattr(0, TCSANOW, &old)<0)
{perror("tcsetattr ICANON");}
if(read(0,&buf,1)<0)
{perror("read()");}
old.c_lflag|=ICANON;
old.c_lflag|=ECHO;
if(tcsetattr(0, TCSADRAIN, &old)<0)
{perror ("tcsetattr ~ICANON");}
//printf("%c\n",buf);
return buf;
}
GameSystem.h
#pragma once
#include "Map.h"
#include <string>
#include <list>
using namespace std;
class GameSystem
{
public:
GameSystem(string mapName); //Constructor
void startGame(); //Start the game
char getch();
void movePlayer();
private:
//int _numberOfMonsters = 5; //We'll make this a random number later
Map _map;
Player _player;
Monster _monster;
Monster _theMonsters[5];
int _x;
int _y;
int _spawnValue;
};
Character.cpp
#include <string>
#include "Character.h"
using namespace std;
Character::Character(){
}
char Character::getToken(){
return _token;
}
void Character::setLocation(int x, int y){
_x = x;
_y = y;
}
void Character::getLocation(int &x, int &y){
x = _x;
y = _y;
}
Character.h
#pragma once
#include <string>
class Character{
public:
Character();
char getToken();
void setLocation(int x, int y);
void getLocation(int &x, int &y);
protected:
int _x;
int _y;
char _token = '!';
};
Map.cpp
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <string>
#include <fstream>
#include <cstring>
#include <random>
#include <ctime>
#include <tuple>
#include "Map.h"
#include <time.h>
Map::Map(){
srand (time(NULL));
}
void Map::load(string levelName){
ifstream theStream;
theStream.open(levelName);
if(theStream.fail()){
perror(levelName.c_str());
system("PAUSE");
exit(1);
}
string line;
while(getline(theStream, line)){
_mapData.push_back(line);
}
theStream.close();
}
void Map::obtainSpawningLocations(char characterToken,Character &_character){
/*
Below code provides all the possible spawning locations for the player
and stores them in an array of tuples.
*/
tuple<int,int> myTuple[600]; //Hard coded 600 value is messy. Change later
int numberOfSpawnPoints = 0;
int upperLimitForNumberGenerator = 0;
/*
The for loop below records all of the possible spawning locations and stores them in the tuple array
*/
for(int i = 0; i<_mapData.size();i++){
for(int j = 0; j<_mapData[i].size();j++){
if(_mapData[i][j]=='.'){
get<0>(myTuple[numberOfSpawnPoints]) = j;
get<1>(myTuple[numberOfSpawnPoints]) = i;
numberOfSpawnPoints++;
}
}
}
upperLimitForNumberGenerator = numberOfSpawnPoints;
int characterCoordinates = rand()%upperLimitForNumberGenerator;
int xCoordinate = get<0>(myTuple[characterCoordinates]);
int yCoordinate = get<1>(myTuple[characterCoordinates]);
_mapData[yCoordinate][xCoordinate] = characterToken; //Remember y is first and x is second
_character.setLocation(xCoordinate, yCoordinate);
}
void Map::print(){
for(int i=0;i<_mapData.size(); i++){
printf("%s\n", _mapData[i].c_str());
}
printf("\n");
}
void Map::checkMovement(char input, Player &aPlayer){
int x;
int y;
aPlayer.getLocation(x,y);
char aLocation;
switch(input) {
case 'w':
case 'W': //If 1 up from the player token is a '.' then we move him up
//via a different function
//Otherwise we do nothing.
aLocation = returnLocation(x,y-1);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y-1][x] = '#';
aPlayer.setLocation(x,y-1);
}
else
cout<<"Can't go here!"<<endl;
break;
case 'a':
case 'A':
aLocation = returnLocation(x-1,y);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y][x-1] = '#';
aPlayer.setLocation(x-1,y);
}
else
cout<<"Can't go here!"<<endl;
break;
case 's':
case 'S':
aLocation = returnLocation(x,y+1);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y+1][x] = '#';
aPlayer.setLocation(x,y+1);
}
else
cout<<"Can't go here!"<<endl;
break;
case 'd':
case 'D':
aLocation = returnLocation(x+1,y);
if(aLocation == '.'){
_mapData[y][x] = '.';
_mapData[y][x+1] = '#';
aPlayer.setLocation(x+1,y);
}
else
cout<<"Can't go here!"<<endl;
break;
default:
cout<<"Invalid input";
system("PAUSE");
break;
}
}
char Map::returnLocation(int x, int y){
cout<<x<<endl;
cout<<y<<endl;
char aSpot = _mapData[y][x];
return aSpot;
}
Map.h
#pragma once
#include <vector>
#include <fstream>
#include <string>
#include <tuple>
#include <ctime>
#include <random>
#include "Player.h"
#include "Monster.h"
using namespace std;
class Map
{
public:
Map(); //Constructor
void load(string levelName);
void obtainSpawningLocations(char characterToken, Character &aCharacter);
void checkMovementMonsters(char input, Monster &aMonster);
//void obtainSpawningLocationsForMonsters(char characterToken, Monster aMonster);
void print();
void checkMovement(char input, Player &aPlayer);
void movement(char characterToken);
char returnLocation(int x,int y);
// int numberOfSpawnPoints;
private:
vector <string> _mapData;
Player _player;
Monster _monster;
};
Monster.cpp
#include <iostream>
#include <string>
#include "Monster.h"
using namespace std;
Monster::Monster(){
}
void Monster::moveAround(){
cout<<"Monster Mash"<<endl;
}
Monster.h
#pragma once
#include <string>
#include "Character.h"
class Monster: public Character{
public:
Monster();
virtual void moveAround();
protected:
char _token = 'M';
int _x;
int _y;
};
Werewolf.cpp
#include <iostream>
#include <string>
#include "Werewolf.h"
using namespace std;
Werewolf::Werewolf(){
}
void Werewolf::moveAround(){
cout<<"Werewolf moving around"<<endl;
}
Werewolf.h
#pragma once
#include <string>
#include "Character.h" //For inheritance/polymorphism
#include "Monster.h"
class Werewolf: public Monster{
public:
Werewolf();
void moveAround();
private:
char _token = 'W';
};
Vampire.cpp
#include <iostream>
#include <string>
#include "Vampire.h"
using namespace std;
Vampire::Vampire(){
}
void Vampire::moveAround(){
cout<<"Vampire moving around"<<endl;
}
Vampire.h
#pragma once
#include <string>
#include "Character.h" //For inheritance/polymorphism
#include "Monster.h"
class Vampire: public Monster{
public:
Vampire();
virtual void moveAround();
private:
char _token = 'V';
};
Player.cpp
Player::Player(){
}
Player.h
#pragma once
#include <string>
#include "Character.h"
using namespace std;
class Player : public Character {
public:
Player();
protected:
int _x;
int _y;
char _token = '#';
};
Main
#include <iostream>
#include "GameSystem.h"
using namespace std;
int main()
{
GameSystem gameSystem("LevelOne.txt");
gameSystem.startGame();
return 0;
}
The level text file:
############################################
#..........................................#
#..........................................#
#...........................^..............#
#..........................................#
#......................#...................#
#......................#...................#
#......................#...................#
#............^.........#...................#
#......######..........#..&................#
#......\...............#...................#
#......................#...................#
#..........................................#
#..........................................#
############################################
There is no virtual dispatch happening on _theMonsters[i].moveAround(). You need to have an array of pointers to objects of type monster. In fact, there are quite some problems in the way you try to set up the class hierarchy, like, having identically named member variables in derived classes.
There are a couple of issues here.
Monster::_token, Werewolf::_token, and Vampire::_token are all different variables. A Werewolf object has both Monster::_token and Werewolf::_token.
Monster _theMonsters[5] is an array of 5 Monster objects. It will never be a Vampire or a Werewolf, always a Monster. There is no virtual dispatch to be done since the objects will always be the same type: Monster.
Virtual dispatch only applies to pointers and references. To make this work, you'll need to use an array of pointers to Monsters: Monster* _theMonsters[5]. Then you can fill it like _theMonsters[i] = new Vampire(). If you do this, you'll need to remember to delete the objects when you're done with them, or you could use a smart pointer like std::unique_ptr or std::shared_ptr instead of raw Monster*s.

C++ ADT proper header files?

I am making my own ADT, the issue I am having is the program won't compile as it crashes with an error C:\Dev-Cpp\Makefile.win [Build Error] [mainpoly.o] Error -1073741819.
I am not sure what that means, but i think it has to do with how i am naming my files (.h,.cpp). Right now I want to get my program to compile so I can test out the bugs in my ADT, i just need help in getting the program to compile at this point, not the errors in the program itself, thank you. I dont know what extension to give to what file (if thats even the core issue) Also, not sure hot to separate the three programs here on the forums, sorry.
Here are the three files
#ifndef POLYNOMIAL_H
#define POLYNOMIAL_H
#include <string>
#include <vector>
struct v{
int coe;
int deg;
};
class polynomial{
private:
vector<v> poly;
public:
~polynomial();
polynomial(int, int);
int degree();
int coeffecient(int);
void changeCoeffcient(int, int);
void mulpoly(int, int);
int addpoly(int, int);
int getpoly();
};
#endif
#include "polynomial.h"
#include <vector>
polynomial::polynomial(int coeffecient, int degree){
coe=coeffecient;
deg=degree;
v t;
t.co=coe;
t.de=deg;
poly.push_back(t);
}
polynomial::~polynomial(){
delete[];
}
int polynomial::degree(){
return poly;
}
int polynomial::coeffecient(power){
int i=power;
int val;
for(int z=0;z<t.size;z++){
if(i=t.de[z]){
val=t.co[z];
break;
}
else{
return 0;
}
}
return val;
}
void polynomial::changeCoeffcient(int newCoeffcient, int power){
int i=power;
for(int z=0;z<t.size;z++){
if(i=t.de[z]){
t.co[z]=newCoeffcient;
break;
}
else{
return 0;
}
}
}
void polynomial::mulpoly(int coeffecient, int mul){
int i=coeffecient;
for(int z=0;z<t.size;z++){
if(i=t.co[z]){
t.co[z]*=mul;
break;
}
else{
return 0;
}
}
}
#include <stdlib.h>
#include <iostream>
#include <polynomial.h>
using namespace std;
int main(){
int i;
polynomial poly(3,5);
i=poly.degree();
cout<<"The value is: "<<i;
system("PAUSE");
return 0;
}

What does "duplicate symbol _heating_unit in BangBangControlTest.o and BangBangControl.o" mean?

Im receiving this error when trying to compile my code.
$ g++ -o BangBangControlTest BangBangControl.o BangBangControlTest.o
ld: duplicate symbol _heating_unit in BangBangControlTest.o and BangBangControl.o for architecture x86_64
collect2: ld returned 1 exit status
I am new to C++ and can't find out what is wrong. I've searched through many tutorials and looked at similar error messages received by other stack users. Here are my classes.
"BangBangControlTest.cpp"
// Test function
#include <iostream>
#include "BangBangControl.h"
using namespace std;
int main(){
BangBangControl control(50, true, 75);
for(int i = 0; i < 50; i++){
std::cout << "Temp = " << control.update() << endl;
}
return 0;
}
"BangBangControl.cpp"
#include <iostream>
#include "BangBangControl.h"
using namespace std;
BangBangControl::BangBangControl(int temp, bool isOn, int initialTemp){
heating_unit = HeatingUnit(isOn, initialTemp);
temp_to_maintain = temp;
}
void BangBangControl::setTemp(int temp){temp_to_maintain = temp;}
int BangBangControl::getTemp(){return temp_to_maintain;}
int BangBangControl::update(){
int b=heating_unit.tick();
if (b > temp_to_maintain + 2) heating_unit.turnOff(); if (b < temp_to_maintain - 2) heating_unit.turnOn();
return b;
}
"BangBangControl.h"
// BangBangControl header
#include <iostream>
#include "HeatingUnit.h"
using namespace std;
HeatingUnit heating_unit;
int temp_to_maintain;
class BangBangControl{
public:
BangBangControl(int, bool, int);
void setTemp(int);
int getTemp();
int update();
};
"HeatingUnit.cpp"
// HeatingUnit class implementation
#include <iostream>
#include "HeatingUnit.h"
using namespace std;
HeatingUnit::HeatingUnit(bool a, int b){
isOn = a;
temp = b;
}
void HeatingUnit::turnOn(){isOn = true;}
void HeatingUnit::turnOff(){isOn = false;}
int HeatingUnit::tick(){
if(isOn && temp <= 100){
return ++temp;
}
else if((!isOn) && temp >= 0){
return --temp;
}
else{
return temp;
}
}
"HeatingUnit.h"
#include <iostream>
using namespace std;
class HeatingUnit{
public:
bool isOn;
int temp;
HeatingUnit();
HeatingUnit(bool, int);
void turnOn();
void turnOff();
int tick();
};
You see that HeatingUnit heating_unit; in your header file? You need to put extern in front of it, and copy the original version without the extern to the .cpp file, optionally specifying an initial value there.
You can read more about this here: How do I use extern to share variables between source files?