You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ SFML井字棋项目出现Duplicate definition error错误排查

问题原因

链接报错的直接原因是头文件中定义了全局变量:
你在grid.h的grid命名空间下直接写了vector<Cell> cells;,这是变量的完整定义。由于grid.h同时被main.cpp和grid.cpp包含,两个源文件单独编译时都会生成一份grid::cells的实体定义,链接阶段检测到重复定义就会抛出你看到的错误。
另外代码里还有3处会导致运行异常的隐藏问题,一并修复即可正常运行。

修复步骤
    1. 修正头文件的变量声明
      打开grid.h,把命名空间里的变量定义改成extern声明,头文件只做声明不做实体定义:
    // 原来的写法:vector<Cell> cells;
    extern vector<Cell> cells;
    
    同时把头文件顶部的头卫宏改成和文件名匹配的,避免后续宏冲突:
    // 原来的#ifndef TILE_H / #define TILE_H
    #ifndef GRID_H
    #define GRID_H
    
    1. 在源文件中补全变量定义
      打开grid.cpp,在#include "grid.h"下方添加变量的实体定义:
    #include "grid.h"
    
    // 补这行:全局变量的唯一实体定义
    vector<grid::Cell> grid::cells;
    
    1. 修正窗口样式的逻辑错误
      打开main.cpp,窗口创建时的样式组合用错了运算符,||是逻辑或,会返回布尔值,无法正确组合窗口样式,要改成按位或|:
    // 原来的写法:sf::Style::Titlebar || sf::Style::Close
    sf::RenderWindow window(sf::VideoMode(500, 500), "TicTacToe", sf::Style::Titlebar | sf::Style::Close);
    
    1. 修正棋盘格子的坐标计算逻辑
      原来的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 03:09:14