结构的多重定义错误,但我在任何地方都看不到错误(C++)
Posted
技术标签:
【中文标题】结构的多重定义错误,但我在任何地方都看不到错误(C++)【英文标题】:Error multiple definition of struct, but i dont see the error anywhere ( C++ ) 【发布时间】:2020-01-05 23:02:07 【问题描述】:制作了一个结构,编译了我的程序,完美运行,没有改变任何东西,关闭了vm,重新启动了vm和vsc,然后再次在控制台中做了,它出现了这个错误
1 warning generated.
linking build/main.o
build/Game.o:(.bss+0x60): multiple definition of `scoreArray'
build/main.o:(.bss+0x10): first defined here
clang-5.0: error: linker command failed with exit code 1 (use -v to see
invocation)
Makefile:33: recipe for target 'build/2048' failed
make: *** [build/2048] Error 1
这是我的代码,我看不到任何重新定义它的东西,请有人帮我找出它, 这是头文件和它使用的源文件
main.cpp
/**
* File: main.cpp
* Author: not lettin u know :)
* Date: 20-11-2019
* Desc:
* Copyright: University of West of England 2017
*/
#include <stdio.h>
#include <cstdio>
#include <stdlib.h>
// include the UFCFGL301's standard library
#include <ufcfgl-30-1.h>
#include <iostream>
#include <time.h>
#include "Grid.h"
#include "Game.h"
// uncomment if you want to use the graphics library
#include <graphics.h>
using namespace std;
using namespace uwe;
/**
* main routine, implements ...
* @return success
*/
int main(void)
srand(time(0));
Game game;
// -------Initialising Game-------
while(1)
game.chooseFunction();
grid.totalScore = 0;
grid.initGrid();
grid.addValue();
cout << "\033[2J"; // this clears the terminal
cout << "\nPlayer Score : " << grid.totalScore << "\n";
std::cout << "\nMoves = " << grid.moves << "\n\nlast input = N/A \n";
grid.setScore(grid.score);
grid.drawGrid();
// This launches graphics window where all keypresses are inputted
// this is also where we start the lambda functions in a loop
initialiseGraphics(600,400);
loop (
[&]()
,
[&](keyPress keyPress)
// w a s d are also inputted into an integer as their respective ascii value
// so this allows the use of w a s d and also the arrow keys in controlling
// the moves of the player
int kpVal = keyPress.getKeyCode();
if ( kpVal == 'q' )
return true;
if ( kpVal == 'w' || kpVal == keyPress::upKey )
cout << "\033[2J"; // this clears the terminal
grid.shiftUp();
cout << "Player Score : " << grid.totalScore << "\n";
std::cout << "\nMoves = " << grid.moves
<< "\n\nlast input = UP \n";
grid.setScore(grid.score);
grid.drawGrid();
game.checkGameState();
if(game.gameFinished == true)
return true;
if ( kpVal == 'a' || kpVal == keyPress::leftKey )
cout << "\033[2J"; // this clears the terminal
grid.shiftLeft();
cout << "Player Score : " << grid.totalScore << "\n";
std::cout << "\nMoves = " << grid.moves
<< "\n\nlast input = LEFT \n";
grid.setScore(grid.score);
grid.drawGrid();
game.checkGameState();
if(game.gameFinished == true)
return true;
if ( kpVal == 's' || kpVal == keyPress::downKey )
cout << "\033[2J"; // this clears the terminal
grid.shiftDown();
cout << "Player Score : " << grid.totalScore << "\n";
std::cout << "\nMoves = " << grid.moves
<< "\n\nlast input = DOWN \n";
grid.setScore(grid.score);
grid.drawGrid();
game.checkGameState();
if(game.gameFinished == true)
return true;
if ( kpVal == 'd' || kpVal == keyPress::rightKey )
cout << "\033[2J"; // this clears the terminal
grid.shiftRight();
cout << "Player Score : " << grid.totalScore << "\n";
std::cout << "\nMoves = " << grid.moves
<< "\n\nlast input = RIGHT \n";
grid.setScore(grid.score);
grid.drawGrid();
game.checkGameState();
if(game.gameFinished == true)
return true;
return false;
);
游戏.h
#pragma once
#include <cstdio>
#include <string>
#include <graphics.h>
#include "Grid.h"
class Game
public:
bool canMove();
bool checkWin();
bool checkLoss();
void checkGameState();
void chooseFunction();
void printHighScores();
void writeHighScore();
bool gameFinished = false;
private:
;
extern Game game;
struct highScore
int score;
std::string name;
;
游戏.cpp
#include "Grid.h"
#include "Game.h"
#include <sstream>
#include <unistd.h>
#include <iostream>
#include <cstdio>
#include <graphics.h>
#include <fstream>
#include <string>
#include <algorithm> //std::sort for array of structs sorting based on struct
// integer
Grid grid;
highScore scoreArray[100];
// functions to check game state for win or loss or can make moves
bool Game::canMove()
bool canMove = false;
for(int x = 0; x < Grid::tilesWide; x++)
for(int y = 0; y < Grid::tilesHigh; y++)
if (grid.grid[x][y] == Grid::emptyCell)
canMove = true;
return canMove;
// multiple if statements due to if grid[3][1] was being checked with
// grid[3+1][1] then it would loop around and check against grid[1][2]
// for an unknown reason, so to combat this i had to check specifically against
// the edge of the board
else if(y == 3 && x < 3)
if( grid.grid[x][y] == grid.grid[x+1][y] )
canMove = true;
return canMove;
else if(x == 3 && y < 3)
if( grid.grid[x][y] == grid.grid[x][y+1] )
canMove = true;
return canMove;
else if( ( x < 3 && y < 3 ) &&
(grid.grid[x][y] == grid.grid[x][y+1] ||
grid.grid[x][y] == grid.grid[x+1][y]) )
canMove = true;
return canMove;
return canMove;
bool Game::checkWin()
bool win = false;
for(int x = 0; x < Grid::tilesWide; x++)
for(int y = 0; y < Grid::tilesHigh; y++)
if(grid.grid[x][y] == 2048)
win = true;
return win;
return win;
bool Game::checkLoss()
bool loss = false;
if(canMove() == false )
loss = true;
return loss;
return loss;
void Game::checkGameState()
if(checkWin() == true)
std::cout << "\n\n--------YOU WIN--------\n\n";
gameFinished = true;
writeHighScore();
else if(checkLoss() == true)
std::cout << "\n\n--------YOU LOSE--------\n\n";
gameFinished = true;
// functions for initializing game/options
void Game::chooseFunction()
while(1)
int function = 0;
std::cout << "\nPlease Choose A Function\n1) Play Game\n2) High Scores"
<< "\n3) Exit Program";
std::cout << "\nFunction : ";
std::cin >> function;
if (std::cin.fail() || function < 1 || function > 3)
std::cin.clear();
std::cin.ignore(1000,'\n'); // this is to stop the validation from
// looping for each wrong character entered
std::cout << "Not a valid option, Please re-enter \n\n" ;
sleep(1);
else if (function == 1)
std::cout << "------Launching Game------\n\n";
std::cout << "---------LOADING---------\n";
for(int x=0;x < 5;x++)
std::cout << "|||||" << std::flush;
sleep(1);
return ;
else if (function == 2)
std::cout << "---Printing High Scores---\n";
std::cout << "---------LOADING---------\n";
for(int x=0;x < 5;x++)
std::cout << "|||||" << std::flush;
sleep(1);
printHighScores();
sleep(10);
else if (function == 3)
std::cout << "-------Now Exiting------- \n\n" << std::flush ;
std::cout << "---------LOADING---------\n";
for(int x=0;x < 5;x++)
std::cout << "|||||" << std::flush;
sleep(1);
exit(0);
// This function is called upon a win, and writes the high score ,of those who
// win the game, into a text file under the format of SCORE - NAME
void Game::writeHighScore()
std::string name;
std::cout << "\nEnter Name To Store High Score ( Max 16 Characters )\n"
<< "Name : ";
std::getline(std::cin,name);
// this is to stop the string being over 16 characters
if(std::cin.fail() || name.length() > 16)
std::cout << "\n\nPlease Enter A Max of 16 Characters\n\n";
writeHighScore();
return;
else
// This opens the output stream to the high scores text file
// and immediately points to the next free line in the file
std::ofstream HighScore;
HighScore.open ("HighScores.txt", std::ios::app);
HighScore << grid.totalScore << " "<< name << std::endl;
HighScore.close();
return;
// simple comparator function to be used with std::sort in order to sort
// the array of structs containing scores and their respective player names
bool sortScore(highScore a,highScore b)
return a.score > b.score;
// this function prints the high scores from the text file, however
// im not sure how to sort a text file each time its appended, so instead
// when this function is called, it seperates the lines of the files into
// the score and their respective player name, these are stored in a struct
// object for each line, and then the array of structs is sorted using
// std::sort and the comparator function and then the first 10 scores and names
// in the struct array are printed, TLDR, prints Top 10 scores :)
//
// not on the spec for the assignment but i enjoyed learning about how
// i would go about making something like this :)
void Game::printHighScores() // function to choose and print ascii art
std::ifstream highScores;
highScores.open("HighScores.txt");
std::string line;
int i=0;
if(!highScores)
std::cout << "\nCould Not Open HighScores.txt";
sleep(2);
return;
else
while(getline(highScores, line))
std::istringstream iss(line);
int score;
std::string name;
// this seperates out the score and the name string from each line in the file
if(!(iss >> score && iss.ignore() && std::getline(iss,name)))
break;
// this adds to the array of structs defined in the header file
scoreArray[i].score = score;
scoreArray[i].name = name;
i++;
std::sort(&scoreArray[0],&scoreArray[100],sortScore);
// and finally... this prints the top 10 scores
std::cout << "\n\n-------HIGH SCORES-------\n\n";
for(int i=0; i<10; i++)
std::cout <<i+1<<") "<<scoreArray[i].score<<" - "<<scoreArray[i].name
<<"\n";
【问题讨论】:
问题标题中无需添加unsolved
或solved
。这就是接受答案的目的。
哦,我只是以为人们正在阅读它,看到一个有效的答案,并没有发布任何可能有帮助的东西,因为他们可能认为有效的答案解决了问题
【参考方案1】:
线
highScore scoreArray[100];
只要包含此标头,您的标头就会声明一个变量。我假设该标头包含在多个源文件中。
将其移动到.cpp
中并将extern
添加到标题中。
基本上,对于包含此标头的每个源文件,您都在声明一个名为 scoreArray
的变量。每个包含此标头的.cpp
都将声明自己的scoreArray
。链接器在进行链接时会遇到两个具有相同名称的变量,并且无法确定哪个是“正确的”,因此它放弃并生成您所看到的错误。
因此,您需要将定义移动到 .cpp
中,并在标题中将其作为外部引用。 (有几种不同的方法。选择最适合您的方法。)
【讨论】:
哦,所以在源文件的头文件中声明结构数组不起作用? 您的标头可以包含数组的extern
声明,但如果标头被多个源文件使用,则它实际上必须在 .cpp 中定义。预处理时,编译器基本上在编译之前将任何#include
'd 文件的内容粘贴到包含源中。
也将 highScore scoreArray[100] 移动到 cpp 文件中不起作用,它仍然显示多个定义:S
@meme 你注释掉声明会发生什么?
未声明标识符'scoreArray'的一堆错误对我来说毫无意义:(以上是关于结构的多重定义错误,但我在任何地方都看不到错误(C++)的主要内容,如果未能解决你的问题,请参考以下文章