-4

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.

Community
  • 1
  • 1
George_E -old
  • 188
  • 1
  • 3
  • 17
  • Reduce. Pick one error. Remove stuff until the problem goes away, then explore the relationship between the removed stuff and the error. If you can't figure it out, you now have a [mcve] you can put in the question. What you have now is useless. According to the error message `status` is defined at least twice, but is not found even once in the code provided. – user4581301 Jan 21 '18 at 18:18
  • @user4581301 I have added in the code where `status` is. Also, these errors come together anyway. I don't want to minimize code too much, because otherwise I might miss out the real problem. – George_E -old Jan 21 '18 at 18:22
  • Am trying to work out why this line compiles: `extern sf::RenderWindow Window(sf::VideoMode(500, 500), "Maximize window to play the game");` anyway is not a normal extern declaration. ... Looks like it's an extern definition - that will get you multiple definition errors. – Richard Critten Jan 21 '18 at 18:22
  • @RichardCritten took out the extern, exact same errors. I will put extern back for now though, just so I don't mess anything up – George_E -old Jan 21 '18 at 18:25
  • 3
    It's not the extern that is wrong it's the initialisation in the header file. Move the initialisation to one .cpp file and remove the initialisation from the header file leaving it just extern. Every .cpp file that includes `Global.h` defines (not just declares) a new `sf::RenderWindow Window` and when you link you have too many of them. – Richard Critten Jan 21 '18 at 18:26
  • George it is impossible to minimize too much and still have a complete example. the idea is to divide and conquer to produce a code example that exhibits the exact same bad behaviour with as little code as possible. If you can get the problem down to a couple lines of code, it's usually pretty easy to see where the problem is even if you don't know why it's a problem. – user4581301 Jan 21 '18 at 18:27
  • 1
    Here is a good rundown of `extern` and how to use it: [When to use extern in C++](https://stackoverflow.com/questions/10422034/when-to-use-extern-in-c) – user4581301 Jan 21 '18 at 18:28
  • @RichardCritten So what should my Global.h look like, and what will the file where I will move the definitions to (main.cpp)? – George_E -old Jan 21 '18 at 18:32
  • @RichardCritten Problem solved! Thank you very much! I will edit my question and put in the solution :) – George_E -old Jan 21 '18 at 18:39
  • 1
    @George_E: Please don't edit the solution into the question, and don't add "[SOLVED]" to the title. You can post the solution as an answer and then accept it (and then roll back your recent edit). – Keith Thompson Jan 21 '18 at 18:56

1 Answers1

0

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";
George_E -old
  • 188
  • 1
  • 3
  • 17