c++ - 仅在 CodeBlocks 中出现“多重定义”错误
问题描述
我正在使用 MVC 构建井字游戏。代码如下:
主.cpp:
#include "controller.cpp"
int main()
{
Controller controller;
controller.start_game();
}
控制器.hpp:
#ifndef controllerTTT
#define controllerTTT
#include <iostream>
#include <array>
#include <string>
#include "common.hpp"
#include "model.cpp"
#include "view.cpp"
#define BOARD_SIZE 3
class Controller
{
private:
Model model;
View view;
bool player_interaction(Player);
void single_game();
public:
void start_game();
};
#endif
控制器.cpp:
#include "controller.hpp"
bool Controller::player_interaction(Player player){
//code eliminated in order to not post 300 lines of code
}
void Controller::single_game(){
//code eliminated in order to not post 300 lines of code
}
void Controller::start_game(){
//code eliminated in order to not post 300 lines of code
}
模型.hpp:
#ifndef modelTTT
#define modelTTT
#include <array>
#include "common.hpp"
#define BOARD_SIZE 3
class Model
{
private:
Player board[BOARD_SIZE][BOARD_SIZE];
public:
Model();
void do_move(Move_input, Player);
bool legal_move(Move_input);
Outcome outcome();
std::array<Player, BOARD_SIZE*BOARD_SIZE> get_board();
void reset();
};
#endif
模型.cpp:
#include "model.hpp"
Model::Model()
{
for(int row=0; row<BOARD_SIZE; ++row)
{
for(int column=0; column<BOARD_SIZE; ++column)
{
this->board[row][column]=Player::none;
}
}
}
void Model::do_move(Move_input move_input , Player player)
{
//code eliminated in order to not post 300 lines of code
}
bool Model::legal_move(Move_input move_input)
{
//code eliminated in order to not post 300 lines of code
}
Outcome Model::outcome()
{
//code eliminated in order to not post 300 lines of code
}
std::array<Player, BOARD_SIZE*BOARD_SIZE> Model::get_board(){
//code eliminated in order to not post 300 lines of code
}
void Model::reset(){
//code eliminated in order to not post 300 lines of code
}
视图.hpp:
#ifndef viewTTT
#define viewTTT
#include <iostream>
#include <array>
#include <windows.h>
#include <string>
#include "common.hpp"
#define BOARD_SIZE 3
class View
{
public:
void output_board(std::array<Player, BOARD_SIZE*BOARD_SIZE>);
void output_message(std::string);
void output_outcome(Outcome);
void wait(int miliseconds);
void reset();
Move_input get_move();
std::string get_message();
};
#endif
视图.cpp:
#include "view.hpp"
void View::output_board(std::array<Player, BOARD_SIZE*BOARD_SIZE> board){
//code eliminated in order to not post 300 lines of code
}
void View::output_message(std::string message){
//code eliminated in order to not post 300 lines of code
}
void View::output_outcome(Outcome outcome){
//code eliminated in order to not post 300 lines of code
}
void View::wait(int miliseconds){
//code eliminated in order to not post 300 lines of code
}
void View::reset(){
//code eliminated in order to not post 300 lines of code
}
Move_input View::get_move(){
//code eliminated in order to not post 300 lines of code
}
std::string View::get_message(){
//code eliminated in order to not post 300 lines of code
}
common.hpp:
#pragma once
enum class Player
{
none='-',
player1='X',
player2='O'
};
enum class Outcome
{
none,
win1='X',
win2='O',
draw
};
struct Move_input{
int row,column;
};
在 Code::Blocks 中编译时出现以下错误:
但是,当我使用此命令在控制台中构建它时,g++ -std=c++11 main.cpp
它工作得很好。那么我的代码有什么问题?
解决方案
问题有两个方面:
首先,如前所述,
#include
您使用源文件而不是头文件。其次,您的 IDE(代码块)项目已经列出了源文件(它必须列出,否则您不会得到错误)。
在解释为什么上述两点共同作用会导致您遇到的问题之前,您需要了解如何使用 C++ 构建应用程序。要制作 C++ 应用程序,您需要执行三个步骤:
- 编辑一个或多个源文件
- 将源文件编译成目标文件
- 将目标文件链接到单个可执行文件中。
即使您没有显式创建目标文件(如使用g++ -std=c++11 main.cpp
命令),目标文件也是由g++
前端程序隐式创建的。
现在回到你遇到的问题......
因为您的 CodeBlocks 项目列出了所有源文件,所以它们将显式构建到目标文件中,然后链接到最终的可执行程序中。问题是许多符号已经在单个main.o
目标文件中定义,因为您是#include
源文件。因此(例如)符号Controller::single_game
将在 object filemain.o
和object file中定义controller.o
。这是不允许的。
你可以通过只在任何地方包含头文件来解决这个问题。文件中的源代码.cpp
将由 CodeBlocks 为您构建和链接。
推荐阅读
- r - 如果源节点和目标节点具有相同的名称,如何使用 networkD3 创建 sankey 图
- azure-devops - XML 文件中存在的应用程序配置的 Azure Dev Ops 自动化
- sql-server - 在 ms-sql 的单个更改语句中添加新列并更改现有列
- python - 如何修改我的代码以提供 dict 数据类型的输入?
- json - 从xml转换时获取可用的Json
- excel - 动态创建的复选框总是不返回正确的值(真/假)
- angular - 在我的应用程序中,向所有不需要的 mat-select 添加空 mat-option
- php - 如何在 Laravel 中按字母顺序对项目进行排序?
- python - 确定 Flask 请求中的客户端端口
- c# - 使用按钮以新形式创建它们