仅在代码块中出现“多个定义”错误

时间:2018-12-26 10:30:54

标签: c++ class compiler-errors

我正在使用MVC构建井字游戏。代码如下:

main.cpp:

#include "controller.cpp"

int main()
{
    Controller controller;
    controller.start_game();
}

controller.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

controller.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
}

model.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

model.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
}

view.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

view.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在控制台中构建它时,它就可以正常工作。那么我的代码有什么问题呢?

1 个答案:

答案 0 :(得分:3)

问题有两个:

  • 首先,如上所述,您#include是源文件,而不是头文件。

  • 第二,您的IDE(CodeBlocks)项目已经列出了源文件(必须,否则您将不会得到错误)。

在解释为什么以上两点共同导致您遇到的问题之前,您需要学习如何使用C ++来构建应用程序。要制作C ++应用程序,您需要执行三个步骤:

  1. 编辑一个或多个源文件
  2. 将源文件编译为目标文件
  3. 将目标文件链接到单个可执行文件中。

即使您没有显式创建目标文件(如使用g++ -std=c++11 main.cpp命令一样),目标文件也是由g++前端程序隐式创建的。

现在回到您遇到的问题...

由于您的CodeBlocks项目列出了 all 所有源文件,因此它们将显式地构建到目标文件中,然后链接到最终的可执行程序中。问题在于,因为您是main.o源文件,所以许多符号已在单个#include对象文件中定义。因此,例如,Controller::single_game符号将在目标文件main.o的目标文件controller.o 中定义。那是不允许的。

您只需在所有位置包括头文件来解决此问题。 .cpp文件中的源代码将由CodeBlocks为您构建和链接。