LNK2005 Already Defined error when linking my library [duplicate] - c++

This question already has answers here:
error LNK2005, already defined?
(8 answers)
Closed 3 years ago.
I've made a library when i try and use it in another project i get a LNK2005 error.
Structs.h
#pragma once
#ifndef STRUCTS_H
#define STRUCTS_H
#include <vector>
#include <string>
namespace Structs
{
struct GameObject
{
std::string name;
struct PosPoints
{
double px;
double py;
};
std::vector<PosPoints> Points;
double centroid[2];
bool active;
bool init;
};
std::vector<GameObject> objects;
}
#endif
Structs.cpp
#include "stdafx.h"
#include "Structs.h"
struct Structs::GameObject gameObject;
std::vector<Structs::GameObject> objects;
CoreFuncs.cpp
#include "stdafx.h"
#include "CoreFuncs.h"
#include "Structs.h"
#include <GLFW/glfw3.h>
//render
extern struct Structs::GameObject gameObject;
void RenderShapes()
{
for (int i = 0; i < Structs::objects.size(); i++)
{
for (int j = 0; j < Structs::objects[i].Points.size()-1; j++)
{
glBegin(GL_LINES);
glVertex3f(Structs::objects[i].Points[j].px, Structs::objects[i].Points[j].py, 0);
glVertex3f(Structs::objects[i].Points[j + 1].px, Structs::objects[i].Points[j + 1].py, 0);
glVertex3f(0.1, 0.1, 0);
glVertex3f(0.9, 0.9, 0);
glEnd();
}
}
}
The issue stops happening when i comment out the #include "Structs.h" in CoreFuncs.cpp So I assume that inlcude is what is causing the issues. I have looked around and found many sources using extern but i cant seem to get it working here.

Your header file is declaring an actual variable instance named objects. Every translation unit that #includes your header file will get its own copy of that variable. So when you link multiple such units together into a single executable, you will get errors about all of the duplicate variables.
It looks like you want the variable to be instantiated only once in your Structs.cpp file and then shared by your other units. So the variable needs to be declared as extern in your header file. You should also move the extern declaration of the gameObject variable from out of your CoreFuncs.cpp file and place it in your header file, too.
Structs.h
#pragma once
#ifndef STRUCTS_H
#define STRUCTS_H
#include <vector>
#include <string>
namespace Structs
{
struct GameObject
{
std::string name;
struct PosPoints
{
double px;
double py;
};
std::vector<PosPoints> Points;
double centroid[2];
bool active;
bool init;
};
extern std::vector<GameObject> objects;
extern GameObject gameObject;
}
#endif
Structs.cpp
#include "stdafx.h"
#include "Structs.h"
namespace Structs {
std::vector<GameObject> objects;
GameObject gameObject;
}
CoreFuncs.cpp
#include "stdafx.h"
#include "CoreFuncs.h"
#include "Structs.h"
#include <GLFW/glfw3.h>
//render
void RenderShapes()
{
for (size_t i = 0; i < Structs::objects.size(); ++i)
{
Structs::GameObject &go = Structs::objects[i];
for (size_t j = 0; j < go.Points.size()-1; ++j)
{
PosPoints &pt1 = go.Points[j];
PosPoints &pt2 = go.Points[j + 1];
glBegin(GL_LINES);
glVertex3f(pt1.px, pt1.py, 0);
glVertex3f(pt2.px, pt2.py, 0);
glVertex3f(0.1, 0.1, 0);
glVertex3f(0.9, 0.9, 0);
glEnd();
}
}
}

Related

Headers file doesn't see global variables

I have 2 two files called main.cpp and Volum_sumar.cpp. I included Volum_sumar.cpp in main.cpp header, but it doesn't see global variables in main.cpp
Can someone tell where is my mistake?
//main.cpp
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <string>
#include <windows.h>
#include "Volum_sumar.cpp"
using namespace std;
fstream f("Figuri.txt");
fstream d("Dimens.txt");
int n=0;
struct Sfere
{
string codsf;
char culoare [15];
char material[15];
float xc,yc,r,arie,volum;
} sf[100],aux;
int main()
{
cazul3();
}
// Volum_sumar.cpp
#include <iostream>
#include <fstream>
#include <cstring>
#include <cmath>
#include <string>
#include <windows.h>
using namespace std;
void cazul3(){
double volt=0;
for(int i=0;i<n;i++)
{
volt=volt+sf[i].volum;
}
cout<<"VOLUMUL SFERELOR INREGISTRARE ESTE DE : "<<volt<<"cm3"<<endl;
}
You are going about this all wrong.
Like #CruzJean said, by including Volum_sumar.cpp directly in main.cpp, you are trying to access n and sf before they have even been defined.
#include'ing cpp files in other cpp files is bad practice. You should #include only header files. You are supposed to declare shared items in header files that cpp files can #include at needed, then compile your cpp files individually, and then finally link the resulting object files together to make the final executable file.
Global variables that need to be accessed across cpp files need to be instantiated in one cpp file and declared as extern in other files. The linker will resolve the extern references.
Try something more like this instead:
shared.h
#ifndef shared_h
#define shared_h
#include <string>
struct Sfere {
std::string codsf;
char culoare [15];
char material[15];
float xc, yc, r, arie, volum;
};
extern Sfere sf[100];
extern int n;
#endif
main.cpp
#include <fstream>
#include "shared.h"
#include "Volum_sumar.h"
std::fstream f("Figuri.txt");
std::fstream d("Dimens.txt");
int n = 0;
Sfere aux;
int main() {
cazul3();
}
Volum_sumar.h
#ifndef Volum_sumar_h
#define Volum_sumar_h
void cazul3();
#endif
Volum_sumar.cpp
#include <iostream>
#include "shared.h"
#include "Volum_sumar.h"
void cazul3() {
double volt = 0;
for(int i = 0;i < n; ++i) {
volt = volt + sf[i].volum;
}
std::cout << "VOLUMUL SFERELOR INREGISTRARE ESTE DE : " << volt << "cm3" << std::endl;
}

Error LNK2005 and LNK1169 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
There are many questions on this, but none solve my problem. I am trying to use multiple files. I have no idea where the problem is, so I will include all the top lines (#include, #pragma, etc.)
This problem arose when I was creating the class for Cubes.cpp (and in Cubes.h).
main.cpp
#include <iostream>
#include "Cubes.h"
#include "Common functions.h"
#include "Global.h"
#include <SFML/Graphics.hpp>
Cubes.cpp
#include <iostream>
#include "Cubes.h"
#include "Common functions.h"
#include "Global.h"
#include <SFML\Graphics.hpp>
#include <vector>
#include <string>
// Later on in code, where I think it went wrong:
Render::Render()
{
this->rot;
this->boxCoords;
this->rlBoxCol;
this->gridSize;
this->cubeSize;
this->offset;
}
void Render::setRotation(std::vector<float> setRot)
{ // Set rotation
rot = setRot;
}
std::vector<float> Render::getRotation()
{ // Get rotation
return rot;
}
void Render::setCoordinates(std::vector<int> setBoxCoords)
{
boxCoords = setBoxCoords;
}
std::vector<int> Render::getCoordinates()
{
return boxCoords;
}
void Render::setColours(std::vector<std::string> setRlBoxCol)
{
rlBoxCol = setRlBoxCol;
}
std::vector<std::string> Render::getColours()
{
return rlBoxCol;
}
void Render::setSizeOfGrid(int setGridSize)
{
gridSize = setGridSize;
}
int Render::getSizeOfGrid()
{
return gridSize;
}
void Render::setSizeOfCubes(int setCubeSize)
{
cubeSize = setCubeSize;
}
int Render::getSizeOfCubes()
{
return cubeSize;
}
void Render::setOffset(std::vector<int> setOffset)
{
offset = setOffset;
}
std::vector<int> Render::getOffset()
{
return offset;
}
void Render::display()
{
// Long code, not going to show it
}
Cubes.h
#pragma once
#include <vector>
#include <string>
// Also later on in Cubes.h ...
class Render
{
private:
std::vector<float> rot;
std::vector<int> boxCoords;
std::vector<std::string> rlBoxCol;
int gridSize;
int cubeSize;
std::vector<int> offset;
public:
Render();
void setRotation(std::vector<float> setRot);
std::vector<float> getRotation();
void setCoordinates(std::vector<int> setBoxCoords);
std::vector<int> getCoordinates();
void setColours(std::vector<std::string> setRlBoxCol);
std::vector<std::string> getColours();
void setSizeOfGrid(int setGridSize);
int getSizeOfGrid();
void setSizeOfCubes(int setCubeSize);
int getSizeOfCubes();
void setOffset(std::vector<int> setOffset);
std::vector<int> getOffset();
void display();
};
Common functions.cpp
#include <iostream>
#include "Common functions.h"
#include <vector>
#include <string>
Common functions.h
#pragma once
#include <vector>
Global.h
#pragma once
#include <SFML\Graphics.hpp>
extern sf::RenderWindow Window(sf::VideoMode(500, 500), "Maximize window to play the game");
extern std::string status = "NULL";
With the errors:
LNK2005
"class sf::RenderWindow Window" (?Window##3VRenderWindow#sf##A) already defined in Cubes.obj
C:\Users\George\Documents\C++\Projects\Don't fall\Don't fall\main.obj 1
.
LNK2005
"class std::basic_string,class std::allocator > status" (?status##3V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##A) already defined in Cubes.obj
C:\Users\George\Documents\C++\Projects\Don't fall\Don't fall\main.obj 1
.
LNK1169
one or more multiply defined symbols found
C:\Users\George\Documents\C++\Projects\Don't fall\Debug\Don't fall.exe 1
.
I have been stuck on this problem for a while, so any help would be greatly appreciated!
EDIT
I answered my own question, as no one found a solution.
Solution (solved my own problem)
In Global.h, I changed the code to:
#pragma once
#include <SFML\Graphics.hpp>
extern sf::RenderWindow Window;
extern std::string status;
and in Cubes.cpp, I changed it to:
#include <iostream>
#include "Cubes.h"
#include "Common functions.h"
#include "Global.h"
#include <SFML\Graphics.hpp>
#include <vector>
#include <string>
sf::RenderWindow Window(sf::VideoMode(500, 500), "Maximize window to play the game");
std::string status = "NULL";

How do I work with these classes? [duplicate]

This question already has answers here:
Link error when declaring public static variables in C++
(2 answers)
Closed 6 years ago.
I am new to C++ and I am trying to start a project where every time I create a new instance of the ATM class it incements accountID by 1 and displays the current account ID.
This is my code:
// Bank ATM.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include "ATM.h"
int main()
{
ATM abunch[15];
for (int i = 0; i < 15; i++){
abunch[i] = ATM();
}
return 0;
}
//ATM.h
#include "stdafx.h"
#ifndef atm
#define atm
class ATM {
static int accountID;
public:
ATM();
};
int ATM::accountID = 0;
#endif
//ATM.cpp
#include "stdafx.h"
#include "ATM.h"
#include <iostream>
ATM::ATM() {
++accountID;
std::cout << accountID;
}
I get The following error message:
What am I doing wrong?
Because ATM::accountID is declared in a .h file, outside of a class, it is globally declared every time that file is included in another file. You include it twice; in main.cpp and in ATM.cpp. That's a no-no.
The declaration needs to move to ATM.cpp
//ATM.h
#include "stdafx.h"
#ifndef atm
#define atm
class ATM {
static int accountID;
public:
ATM();
};
int ATM::accountID = 0; // <--- remove this line
#endif
//ATM.cpp
#include "stdafx.h"
#include "ATM.h"
#include <iostream>
int ATM::accountID = 0; // <----put it here
ATM::ATM() {
++accountID;
std::cout << accountID;
}

How to include global library in C++ class? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have the main.cpp, a class Student and a global.h library.
I want the functions of global.h to be acessible everywhere, so I did this.
global.h
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
using namespace std;
#ifndef GLOBAL_H
#define GLOBAL_H
int min(vector<int> v) {
int min = -99999999;
for (unsigned int i = 0; i < v.size(); i++) {
if (v[i] > min) min = v[i];
}
return min;
}
double average(vector<int> v) {
int sum = 0;
for (unsigned int i = 0; i < v.size(); i++) {
sum += v[i];
}
return (double)sum / v.size();
}
#endif /* GLOBAL_H */
Student.h
#include "global.h"
#ifndef STUDENT_H
#define STUDENT_H
class Student {
private:
string name;
vector<int> grades;
public:
Student();
void setName(string name);
void addGrade(int grade);
int getBestGrade();
double getAverageGrade();
};
#endif /* STUDENT_H */
Student.cpp
#include "Student.h"
Student::Student() {
}
void Student::setName(string name) {
this->name = name;
}
void Student::addGrade(int grade) {
this->grades.push_back(grade);
}
int Student::getBestGrade() {
return min(this->grades);
}
double Student::getAverageGrade() {
return average(this->grades);
}
main.cpp
#include "Student.h"
using namespace std;
int main(int argc, char** argv) {
Student a;
a.setName("John");
a.addGrade(15);
a.addGrade(13);
a.addGrade(20);
cout << a.getAverageGrade() << endl;
cout << a.getBestGrade() << endl;
return 0;
}
I get this error:
multiple definition of min(...)
multiple definition of average(...)
It seems I am including "global.h" multiple times. But I don't know where. Indeed, I use include "Student.h" two times. But I think the class won't work if I don't to it like this.
Please, help me find out how to include a global library inside a class.
Thanks
##############################
SOLUTION
Thanks to WhiteViking, I have now a solution.
The global.h must have a global.cpp.
global.h
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
using namespace std;
#ifndef GLOBAL_H
#define GLOBAL_H
int min(vector<int> v);
double average(vector<int> v);
#endif /* GLOBAL_H */
global.cpp
#include "global.h"
int min(vector<int> v) {
int min = -99999999;
for (unsigned int i = 0; i < v.size(); i++) {
if (v[i] > min) min = v[i];
}
return min;
}
double average(vector<int> v) {
int sum = 0;
for (unsigned int i = 0; i < v.size(); i++) {
sum += v[i];
}
return (double)sum / v.size();
}
Your question does not show this in detail, but it seems you are defining funcX and funcY in global.h instead of just declaring them.
The preprocessor will replace all #include statements with the verbatim contents of those include files. This happens recursively. So after preprocessing, the compiler sees a "A.cpp" that includes the contents of global.h with the full definitions of funcX and funcY. (global.h was included indirectly via A.h. ) The same thing happens for Main.cpp.
After compilation, the object files for A.cpp as well as for Main.cpp will contain the compiled definitions of funcX and funcY. The error then happens when these object files are linked together in order to build the final executable. The linker will see multiple definitions of these functions and will error out. (It doesn't know/check/care if these definitions are actually identical.)
The solution is to only declare these functions in global.h and put their definition in a separate .cpp file, say global.cpp. For example:
In global.h:
// declarations only here
int funcX(int x);
int funcY(int x);
In global.cpp:
int funcX(int x)
{
return 2 * x;
}
int funcY(int x)
{
return x + 42;
}
In short: you were violating the so-called One Definition Rule (ODR).

undeclared identifier when function is in cpp file

I'm working on Space Invaders and in my Player Class I'm using a vector of a struct called point to store the coordinates of rockets. For some reason i'm getting "rocketVector : undeclared identifier" when I try to use it in the .cpp file.
Does anyone know why?
I'm still pretty new to C++ and I haven't been able to find a solution on google. it's starting to do my head in now :)
Thanks for any help!
#include <windows.h>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <iostream>
#include <stdio.h>
#include <MMSystem.h>
using namespace std;
class Player
{
public:
Player(void);
~Player(void);
void drawRockets(ISprite *r);
vector<point> rocketVector;
};
Player.cpp
void drawRockets(ISprite *r) {
// Draw appropriate number of rockets
for(int i = 0; i < rocketVector.size(); i++){
if( rocketVector[i].y < 0.0 ){
// Remove rockets off screen
rocketVector.erase(rocketVector.begin() + i);
}
else{
rocketVector[i].y -= 20;
r->draw(int(rocketVector[i].x), int(rocketVector[i].y));
}
}
}
You defined drawRockets as a global function instead of a member function of the Player class.
You need to specify that drawRockets method is a member of the Player class:
void Player::drawRockets(ISprite *r) {
// Draw appropriate number of rockets
for(int i = 0; i < rocketVector.size(); i++){
if( rocketVector[i].y < 0.0 ){
// Remove rockets off screen
rocketVector.erase(rocketVector.begin() + i);
}
else{
rocketVector[i].y -= 20;
r->draw(int(rocketVector[i].x), int(rocketVector[i].y));
}
}
}
You have some errors in your code :
First, when you define a method outside its class, you have to specify it is in a class-scope during the declaration like :
void Player::drawRockets( ISprite *r ) { ... };
// ^^^^^^^^
this will solve your "rocketVector : undeclared identifier" error.
Here the operator of scope (::, two colons) is used to define a member of a class from outside the class definition itself.
Also, it is a very bad practice to to using namespace ... in a header file, you should avoid that.
If you remove the using namespace ... don't forget to transform :
vector<point> rocketVector;
in
std::vector<point> rocketVector;
// ^^^^^