C++ SFML井字棋项目出现Duplicate definition error错误排查
问题原因
链接报错的直接原因是头文件中定义了全局变量:
你在grid.h的grid命名空间下直接写了vector<Cell> cells;,这是变量的完整定义。由于grid.h同时被main.cpp和grid.cpp包含,两个源文件单独编译时都会生成一份grid::cells的实体定义,链接阶段检测到重复定义就会抛出你看到的错误。
另外代码里还有3处会导致运行异常的隐藏问题,一并修复即可正常运行。
修复步骤
- 修正头文件的变量声明
打开grid.h,把命名空间里的变量定义改成extern声明,头文件只做声明不做实体定义:
同时把头文件顶部的头卫宏改成和文件名匹配的,避免后续宏冲突:// 原来的写法:vector<Cell> cells; extern vector<Cell> cells;// 原来的#ifndef TILE_H / #define TILE_H #ifndef GRID_H #define GRID_H- 修正头文件的变量声明
- 在源文件中补全变量定义
打开grid.cpp,在#include "grid.h"下方添加变量的实体定义:
#include "grid.h" // 补这行:全局变量的唯一实体定义 vector<grid::Cell> grid::cells;- 在源文件中补全变量定义
- 修正窗口样式的逻辑错误
打开main.cpp,窗口创建时的样式组合用错了运算符,||是逻辑或,会返回布尔值,无法正确组合窗口样式,要改成按位或|:
// 原来的写法:sf::Style::Titlebar || sf::Style::Close sf::RenderWindow window(sf::VideoMode(500, 500), "TicTacToe", sf::Style::Titlebar | sf::Style::Close);- 修正窗口样式的逻辑错误
- 修正棋盘格子的坐标计算逻辑
原来的Init函数坐标计算逻辑错误,第一次循环就会把格子位置偏移到可视区域外,而且三行位置排布混乱,替换成按行列计算的逻辑即可:
void grid::Init() { std::cout << "initializing grid" << std::endl; const int gap = 10; int cellSize = (500 - gap * 4) / 3; // 算上边框和格子间隙的尺寸 float startPos = gap; for (int row = 0; row < 3; row++) { for (int col = 0; col < 3; col++) { float x = startPos + col * (cellSize + gap); float y = startPos + row * (cellSize + gap); grid::Cell newCell(cellSize, x, y, Color::White); grid::cells.push_back(newCell); } } std::cout << "initialized grid" << std::endl; }- 修正棋盘格子的坐标计算逻辑
改完之后重新执行make命令即可正常编译运行,窗口会正确显示3*3的白色棋盘格子。
内容的提问来源于stack exchange,提问作者Marseel
相关产品推荐
相关产品推荐

