织芜 2024-03-02 11:32 采纳率: 70.8%
浏览 66

Qt出现first defined here 问题

这是我的代码:
widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //全屏
    this->setWindowState(windowState()^Qt::WindowFullScreen);

    this->setLayout(ui->mainLayout);

    ui->mainLayout->setStretchFactor(ui->listWidget,1);
    ui->mainLayout->setStretchFactor(ui->stackedWidget,8);

    this->setStyleSheet("QWidget{background-color:black;}");
    ui->listWidget->setStyleSheet("QListWidget{background-color:black;border:2px solid green}");
    ui->stackedWidget->setStyleSheet("QStackedWidget{background-color:black;border:2px solid green}");

    ui->page->setLayout(ui->menuLayout);

    //网络部分初始化
    xAddr=getLocHostIp();
    is_started=false;

    tcpPort=28692;
    udpPort=28692;

    udpSocket=new QUdpSocket(this);
    udpSocket->bind(udpPort,QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint);
    tcpServer=new QTcpServer(this);
    tcpServer->listen(QHostAddress::Any,tcpPort);
    tcpSocket=new QTcpSocket(this);
    //~网络部分初始化

    init_select();
    init_list();

    //连接
    connect(ui->exitButton,&QPushButton::clicked,this,[=](){
        this->close();
    });
    connect(ui->startButton,&QPushButton::clicked,this,&Widget::start);
    connect(udpSocket,&QUdpSocket::readyRead,this,&Widget::udp_listen);
    connect(tcpSocket,&QTcpSocket::readyRead,this,&Widget::tcp_listen);
}

void Widget::init_select(){
    btngrp=new QButtonGroup(this);

    ui->blue->setStyleSheet("QPushButton:checked{border:2px solid green;}");
    ui->brown->setStyleSheet("QPushButton:checked{border:2px solid green;}");
    ui->gray->setStyleSheet("QPushButton:checked{border:2px solid green;}");
    ui->yellow->setStyleSheet("QPushButton:checked{border:2px solid green;}");

    ui->blue->setCheckable(true);
    ui->brown->setCheckable(true);
    ui->gray->setCheckable(true);
    ui->yellow->setCheckable(true);

    btngrp->addButton(ui->blue);
    btngrp->addButton(ui->brown);
    btngrp->addButton(ui->gray);
    btngrp->addButton(ui->yellow);
    btngrp->setExclusive(true);
}

void Widget::init_list(){
    ui->listWidget->addItem("欢迎你啊,这个游戏叫做MAZE,");
    ui->listWidget->addItem("界面简单粗糙,也算是为了一种风格。");
    ui->listWidget->addItem("游戏中,你陷入一个无法离开的迷宫,");
    ui->listWidget->addItem("没有出口,没有自由,");
    ui->listWidget->addItem("但是可以让另一位迷路的人死去。");
    ui->listWidget->addItem("操作:");
    ui->listWidget->addItem("四个方向键↑↓←→:行走");
    ui->listWidget->addItem("Z:射击");
    ui->listWidget->addItem("记得在右侧选择自己的模样。");
}

void Widget::add_list(QString str){
    ui->listWidget->addItem(str);
}

void Widget::start(){
    //blue-1 brown-2 gray-3 yellow-4
    int chara=0;
    chara=(ui->blue->isChecked()?1:(ui->brown->isChecked()?2:(ui->gray->isChecked()?3:(ui->yellow->isChecked()?4:0))));
    if(chara==0){
        add_list("你还没有选择自己的模样。");
        return;
    }
    xChara=chara;
    is_started=true;
    QDataStream stream(&msg,QIODevice::WriteOnly);
    type=0;
    stream<<type<<xAddr<<chara; //msgType:0
    udpSocket->writeDatagram(msg,QHostAddress::Broadcast,udpPort);
    timer.start(3000);
    connect(&timer,&QTimer::timeout,this,&Widget::msg_timeout);
}

void Widget::msg_timeout(){
    switch(type){
    case 0: //探测
        add_list("还未搜寻到局域网内玩家,请稍等");
        udpSocket->writeDatagram(msg,QHostAddress::Broadcast,udpPort);
        break;
    }
}

void Widget::udp_listen(){
    if(is_started){
        int msgType;

        while(udpSocket->hasPendingDatagrams()){
            rec.clear();
            rec.resize(udpSocket->pendingDatagramSize());
            udpSocket->readDatagram(rec.data(),rec.size());
        }
        QDataStream rea(&rec,QIODevice::ReadOnly);
        rea>>msgType;
        switch(msgType){
        case 0:{
            rea>>yAddr>>yChara;
            if(yAddr!=xAddr){
                if(timer.isActive())timer.stop();
                disconnect(&timer,&QTimer::timeout,this,&Widget::msg_timeout);

//                //反馈对方
//                udpSocket->writeDatagram(msg,QHostAddress::Broadcast,udpPort);

                QString sentence;
                sentence="与"+yAddr.toString()+"连接成功,开始游戏";
                add_list(sentence);
            }
            break;
        }
        }
    }
}

void Widget::connect_to(){
    tcpSocket->connectToHost(yAddr,tcpPort);

    QDataStream wri(&msg,QIODevice::WriteOnly);

    wri<<0<<xAddr;
}

void Widget::tcp_listen(){
    rec.clear();

    rec=tcpSocket->readAll();
    int msgType;
    QDataStream rea(&rec,QIODevice::ReadOnly);
    rea>>msgType;
    switch(msgType){
    case 0:{ //对方响应消息
        rea>>yAddr;
        QString sentence;
        sentence="与"+yAddr.toString()+"连接成功,开始游戏";
        add_list(sentence);

        ui->stackedWidget->setCurrentIndex(1);
        generate_res();
    }
    }
}

void Widget::generate_res(){

}

QString Widget::getLocHostIp(){
    QList<QHostAddress> addrlist=QNetworkInterface::allAddresses();
    foreach(QHostAddress addr,addrlist){
        if(addr.protocol()==QAbstractSocket::IPv4Protocol){
            return addr.toString();
        }
    }
    return 0;
}

Widget::~Widget()
{
    delete ui;
}

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QUdpSocket>
#include<QTcpServer>
#include<QTcpSocket>
#include<QButtonGroup>
#include<QHostAddress>
#include<QNetworkInterface>
#include<QTimer>

#include"maze.hpp"

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

public slots:
    void start();

private:
    Ui::Widget *ui;

    QTimer timer;

    //网络部分
    QHostAddress xAddr;
    QHostAddress yAddr;
    QByteArray msg;
    QByteArray rec;
    bool is_started;

    int tcpPort;
    int udpPort;

    QUdpSocket* udpSocket;
    QTcpServer* tcpServer;
    QTcpSocket* tcpSocket;

    void udp_listen();
    QString getLocHostIp();

    void tcp_listen();
    //~网络部分

    //选角色部分
    int xChara;
    int yChara;

    QButtonGroup* btngrp;
    void init_select();
    //~选角色部分

    //list部分
    void init_list();
    void add_list(QString str);
    //~list部分

    //计时器
    int type;
    void msg_timeout();

    //建立连接
    void connect_to();

    void generate_res();

    //游戏地图
    Maze maze;
};
#endif // WIDGET_H

maze.cpp

#ifndef _MAZE_HPP_
#define _MAZE_HPP_

#include <iostream>
#include <vector>
#include <algorithm>
#include <ctime>
#include <map>
#include <set>

using namespace std;

class Maze {
    public:
        Maze(int row = 0, int col = 0);
        void connect(int i, int j);
        void disconnect(int i, int j);

        vector<int> connected(int i) const; // 修改为接收一个参数
        vector<int> surrounded(int i) const; // 修改为接收一个参数

        int Row() const;
        int Col() const;

        bool isConnected(int i, int j) const;

    private:
        int row;
        int col;
        vector<vector<int> > neighbor;
        vector<vector<int> > surround;
};

Maze::Maze(int row, int col) {
    this->row = row;
    this->col = col;

    for (int i = 0; i < col * row; i++) {
        vector<int> tmp(row * col, 0);
        neighbor.push_back(tmp);
        surround.push_back(tmp);
    }
    for (int i = 0; i < col * row; i++) {
        if ((i - 1) % col != 0)
            surround[i][i - 1] = 1; // 左邻居,排除第一列
        if ((i + 1) % col != 0)
            surround[i][i + 1] = 1; // 右邻居,排除最后一列
        if (i - col >= 0)
            surround[i][i - col] = 1; // 上邻居
        if (i + col < row * col)
            surround[i][i + col] = 1; // 下邻居
    }
}

void Maze::connect(int i, int j) {
    neighbor[i][j] = 1;
    neighbor[j][i] = 1;
}

void Maze::disconnect(int i, int j) {
    neighbor[i][j] = 0;
    neighbor[j][i] = 0;
}

vector<int> Maze::connected(int i) const { // 修正为单参数函数
    vector<int> result;
    for (int t = 0; t < row * col; t++) {
        if (neighbor[i][t] == 1) {
            result.push_back(t);
        }
    }
    return result;
}

vector<int> Maze::surrounded(int i) const { // 修正为单参数函数
    vector<int> result;
    for (int t = 0; t < row * col; t++) {
        if (surround[i][t] == 1) {
            result.push_back(t);
        }
    }
    return result;
}

int Maze::Row() const {
    return row;
}

int Maze::Col() const {
    return col;
}

bool Maze::isConnected(int i, int j) const {
    vector<int> con = this->connected(i);
    auto it = find(con.begin(), con.end(), j);
    if (it != con.end()) {
        return true;
    } else {
        return false;
    }
}

void showMaze(const Maze &m) {
    //自左上角向右下角显示
    int row = m.Row();
    int col = m.Col();

    for (int i = 0; i < col; i++) {
        cout << "_ ";
    }
    cout << endl;

    for (int r = 0; r < row; r++) {
        cout << "|";
        for (int c = 0; c < col; c++) {
            if (m.isConnected(r * col + c, (r + 1)* col + c)) {
                cout << " ";
            } else {
                cout << "_";
            }

            if (m.isConnected(r * col + c, r * col + c + 1)) {
                cout << " ";
            } else {
                cout << "|";
            }
        }
        cout << endl;
    }

}

namespace DFS {
    enum color {
        white,
        gray,
        black
    };

    Maze generate(int row, int col) {
        Maze result(row, col);
        vector<color> record(row * col, white);
        vector<int> current;
        current.reserve(static_cast<size_t>(row * col));

        record[0] = gray;
        current.push_back(0);

        while (current.size() != 0) {
            int index = current.back();
            vector<int> sur = result.surrounded(index);

            // 过滤掉非法的邻居,防止超出边界
            sur.erase(remove_if(sur.begin(), sur.end(), [&](int n) {
                int x = n % col;
                int y = n / col;
                return (x == 0 && index % col == col - 1) || // 右
                       (y == 0 && index / col == row - 1) || // 下
                       (x == col - 1 && index % col == 0) || // 左
                       (y == row - 1 && index / col == 0);   // 上
            }), sur.end());


            random_shuffle(sur.begin(), sur.end(), [](vector<int>::difference_type n)->vector<int>::difference_type{
                return rand() % n;
            });
            int i = 0;

            bool found = false;

            for (; i < sur.size(); i++) {
                if (record[sur[i]] == white) {
                    current.push_back(sur[i]);
                    result.connect(index, sur[i]);
                    record[sur[i]] = gray;
                    found = true;
                    break;
                }
            }

            if (!found) {
                current.pop_back();
                record[index] = black;
            }
        }

        return result;
    }
}

namespace RandomKruskal {
    class UnionFind {
        public:
            UnionFind(int n);
            int find(int n);
            void connect(int i, int j);
            bool connected(int i, int j);

        private:
            vector<int>set;
    };

    UnionFind::UnionFind(int n) {
        for (int i = 0; i < n; i++) {
            set.push_back(i);
        }
    }

    int UnionFind::find(int n) {
        if (set[n] == n) {
            return n;
        } else {
            set[n] = find(set[n]);
            return set[n];
        }
    }

    void UnionFind::connect(int i, int j) {
        set[find(i)] = find(j);
    }

    bool UnionFind::connected(int i, int j) {
        if (find(i) == find(j)) {
            return true;
        } else {
            return false;
        }
    }

    Maze generate(int row, int col) {
        Maze maze(row, col);
        UnionFind set(row * col);
        vector<pair<int, int>>edges;
        for (int i = 0; i < row * col; i++) {
            vector<int>v = maze.surrounded(i);
            for (vector<int>::iterator it = v.begin(); it != v.end(); it++) {
                if (i < *it)
                    edges.push_back(make_pair(i, *it));
            }
        }

        random_shuffle(edges.begin(), edges.end(), [ = ](vector<int>::difference_type n)->vector<int>::difference_type{
            return rand() % n;
        });

        for (vector<pair<int, int>>::iterator it = edges.begin(); it != edges.end(); it++) {
            if (!set.connected(it->first, it->second)) {
                set.connect(it->first, it->second);
                maze.connect(it->first, it->second);
            }
        }
        return maze;
    }
}

namespace RandomPrim {
    Maze generate(int row, int col) {
        Maze result(row, col);
        vector<bool>U(row * col, false);
        U[0] = true;
        set<pair<int, int>>edges;
        edges.insert(make_pair(0, 1));
        edges.insert(make_pair(0, col));

        int current = 0;
        while (!edges.empty()) {
            int pos = rand() % edges.size();
            set<pair<int, int>>::iterator edge = edges.begin();
            advance(edge, pos);

            int f = edge->first;
            int s = edge->second;
            current = (!U[f]) ? f : ((!U[s]) ? s : 0);

            result.connect(f, s);
            U[current] = true;

            //更新edges
            vector<int>sur = result.surrounded(current);
            for (vector<int>::iterator it = sur.begin(); it != sur.end(); it++) {
                f = (current > *it ? *it : current);
                s = (current < *it ? *it : current);
                pair<int, int>path = make_pair(f, s);
                if (!U[f] || !U[s]) {
                    edges.insert(path);
                } else {
                    edges.erase(edges.find(path));
                }
            }
        }
        return result;
    }
}

#endif

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}


出现first defined here问题,是为什么

  • 写回答

5条回答 默认 最新

  • 关注

    织芜 上午好☀️☀️☀️️
    本答案参考ChatGPT-3.5

    出现 "first defined here" 问题通常是因为在代码中存在多次定义相同的变量或函数,导致链接时出现冲突。解决此问题的一般步骤如下:

    1. 检查是否在不同的文件中多次定义了同名的变量或函数。
      • 如果是在不同的文件中定义的同名变量,可能是因为在头文件中声明了变量并在多个源文件中包含了同一个头文件。此时,需要将变量的定义放在一个源文件中,将其它源文件中对该变量的声明改为extern关键字。或者,可以将变量定义为static全局变量,以便限制其作用域,并避免链接冲突。
      • 如果是在不同的文件中定义了同名函数,可能是因为多个源文件包含了相同的源代码文件。此
    评论

报告相同问题?

问题事件

  • 创建了问题 3月2日

悬赏问题

  • ¥20 关于web前端如何播放二次加密m3u8视频的问题
  • ¥20 spring boot集成mqtt的使用问题
  • ¥15 使用百度地图api 位置函数报错?
  • ¥15 metamask如何添加TRON自定义网络
  • ¥66 关于川崎机器人调速问题
  • ¥15 winFrom界面无法打开
  • ¥30 crossover21 ARM64版本安装软件问题
  • ¥15 mymetaobjecthandler没有进入
  • ¥15 mmo能不能做客户端怪物
  • ¥15 osm下载到arcgis出错