在 C++ 中编译多个 .hpp 和 .cpp 文件时出错

Errors When Compiling Multiple .hpp and .cpp Files in c++

我刚开始攻读 CS 学位,对实际编程是全新的,因此实施起来很困难。我最近有一个任务让我很困惑。我很困惑,因为我无法 link 将所有文件放在一起(2 个头文件 .hpp 和 2 个实现文件 .cpp)。作业来来去去我很好奇如何将所有文件 link 放在一起,因为我知道在编译时 Board.hpp 和 Board.cpp 文件将编译到一个文件中,TicTacToe.hpp 和 TicTacToe.cpp 文件将编译成一个文件,然后所有两个编译文件将 link 相互编译以生成可执行文件。

这是我尝试在 g++ 中编译时遇到的错误:

TicTacToe.hpp:1:9: warning: #pragma once in main file
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

我不知道那是什么意思。

我将 post 以下文件供您审阅。感谢您提供的任何帮助。再一次,我在这方面是全新的,所以如果你能简单地解释一下,我将非常感激。

Board.hpp

#ifndef BOARD_HPP
#define BOARD_HPP

#include <iostream>
#include <string>


class TTTBoard
{
private:
char Board[3][3];           //creates array
int play();                 // prototype for play function
void makeMove();            //prototype for makeMove function
int turn(int);              //prototype for turn function
int check(int, int);        //prototypr for check function
void print(char x[][3]);    //prototype for print function
int gameState(char x[][3]); //prototype for gameState fuction
int player1, player2, draw, player, winner, done;   //creates variables to be used.
int row, col;               //creates variables to be used in gamestate function

public:
int TtlGames, TtlP1, TtlP2, TtlDraws;   //creates variables that will define gamestate
void intBoard();                        //prototype for intboard
};
#endif

下一个有点长

Board.cpp

    #include "Board.hpp"

    #include <iostream>
    #include <iomanip>


    void TTTBoard::intBoard()               //function to initialize the board
    {                                       //initialzes the variables in order
    done = false;                       // to be used for later functions
    winner = 0;
    player = 2;
    player1 = 1;
    player2 = 2;
    draw = 3;
    int i, k;
    for (k = 0; k<3; k++)               //initializes array to 0
    {
        for (i = 0; i<3; i++)
        {
            Board[k][i] = 0;
        }
    }
    play();                             //begins the game
    }


    int TTTBoard::check(int row, int col)   //checks if spot if occupied
    {
    if (Board[row][col] == 0)
    {
        return true;
    }
    else if (Board[row][col] != 0)
    {
        std::cout << "That square is already taken.";
        return false;
    }
    else
    {
        std::cout << "Checking for win.";
        gameState(Board);
    }
    return false;
    }

    void TTTBoard::makeMove()           //records players move
    {
    player = turn(player);
    int answer = false;
    while (answer == false)
    {
        std::cout << "Player" << turn(player) << ": please enter your move\n";
        std::cin >> row, col;
        answer = check(row, col);
    }

    if (player == 1)
        Board[row][col] = 'X';
    else if (player == 2)
        Board[row][col] = 'O';
    else
        std::cout << "Failed.";
}

int TTTBoard::gameState(char x[][3])    //checks for a win or a draw
{
    winner = 0;
    int count = 0;
    int a = row;
    int b = col;
    for (a = 0; a<3; a++)
    {
        for (b = 0; b<3; b++)
        {
            if (Board[a][b] == 0)
            {
                count++;
            }
        }
    }
    if (count > 0)
    {
        int row, col, xCheck, oCheck;
        for (row = 0; row<3; row++)
        {
            xCheck = 0;
            oCheck = 0;

            for (col = 0; col<3; col++)
            {
                if (x[row][col] == 'X')
                    xCheck++;
                if (x[row][col] == 'O')
                    oCheck++;
                if (oCheck == 3)
                {
                    winner = 2;
                }
                if (xCheck == 3)
                {
                    winner = 1;
                }
            }
        }
        for (col = 0; col<3; col++)
        {
            xCheck = 0;
            oCheck = 0;
            for (row = 0; row<3; row++)
            {
                if (x[row][col] == 'X')
                    xCheck++;
                if (x[row][col] == 'O')
                    oCheck++;
                if (oCheck == 3)
                {
                    winner = 2;
                }
                if (xCheck == 3)
                {
                    winner = 1;
                }
            }
        }
        if (x[0][0] == 'X' && x[1][1] == 'X' && x[2][2] == 'X')
        {
            winner = 1;
        }
        else if (x[0][0] == 'O' && x[1][1] == 'O' && x[2][2] == 'O')
        {
            winner = 2;
        }
        else if (x[2][0] == 'X' && x[1][1] == 'X' && x[0][2] == 'X')
        {
            winner = 1;
        }
        else if (x[2][0] == 'O' && x[1][1] == 'O' && x[0][2] == 'O')
        {
            winner = 2;
        }
    }
    else if (count == 9)
    {
        std::cout << "Its a draw.";
        winner = 3;
    }
    else
    {
        std::cout << "It is the next players turn\n\n";
    }
    if (winner > 0)
    {
        done = true;
    }
    return done;
}


void TTTBoard::print(char Board[][3])       //prints current board state
{
    std::cout << "\n";
    std::cout << "  0  1  2\n";
    std::cout << "0 " << Board[0][0] << "  " << Board[0][1] << "  " << Board[0][2] << " \n";
    std::cout << "1 " << Board[1][0] << "  " << Board[1][1] << "  " << Board[1][2] << " \n";
    std::cout << "2 " << Board[2][0] << "  " << Board[2][1] << "  " << Board[2][2] << " \n";
}

这个也很长

TicTacToe.hpp

#ifndef TICTACTOE_HPP
#define TICTACTOE_HPP

#include "Board.hpp"
#include <iostream>
#include <string>
#include <iomanip>

class Board;        //creates a board to be forward declared

class TicTacToe     //creates tictactoe class
{
private:
    int check(int, int);
    int turn(int player);
    int play();                     //prototype for play method
    int gameState(char x[][3]);
public:
    int TtlGames, TtlP1, TtlP2, TtlDraws;
    void intBoard();
    Board* playBoard;               //forward declarations for use in functions
    Board* print;
    Board* makeMove;
    Board* BoardT;
};

#endif

TicTacToe.cpp

#include "Board.hpp"
#include "TicTacToe.hpp"

#include <iostream>
#include <string>

void TTTBoard::intBoard()       //initializes board
{
    done = false;
    winner = 0;
    player = 2;
    player1 = 1;
    player2 = 2;
    draw = 3;
    int i, k;
    for (k = 0; k<3; k++)
    {
        for (i = 0; i<3; i++)
        {
            Board[k][i] = 0;
        }
    }
    play();
}

int TicTacToe::turn(int player)         //informs players of whose turn it is.
{
    switch (player)
    {
    case 1: player = 2;
    {
        std::cout << "\nPlayers 1 turn.\n\n";
        break;
    }
    case 2: player = 1;
    {
        std::cout << "\nPlayers 2 turn.\n\n";
        break;
    }
    }
    return player;
}

int TTTBoard::gameState(char x[][3])        //checks for win or draw
{
    winner = 0;
    int count = 0;
    int a = row;
    int b = col;
    for (a = 0; a<3; a++)
    {
        for (b = 0; b<3; b++)
        {
            if (Board[a][b] == 0)
            {
                count++;
            }
        }
    }
    if (count > 0)
    {
        int row, col, xCheck, oCheck;
        for (row = 0; row<3; row++)
        {
            xCheck = 0;
            oCheck = 0;

            for (col = 0; col<3; col++)
            {
                if (x[row][col] == 'X')
                    xCheck++;
                if (x[row][col] == 'O')
                    oCheck++;
                if (oCheck == 3)
                {
                    winner = 2;
                }
                if (xCheck == 3)
                {
                    winner = 1;
                }
            }
        }
        for (col = 0; col<3; col++)
        {
            xCheck = 0;
            oCheck = 0;
            for (row = 0; row<3; row++)
            {
                if (x[row][col] == 'X')
                    xCheck++;
                if (x[row][col] == 'O')
                    oCheck++;
                if (oCheck == 3)
                {
                    winner = 2;
                }
                if (xCheck == 3)
                {
                    winner = 1;
                }
            }
        }
        if (x[0][0] == 'X' && x[1][1] == 'X' && x[2][2] == 'X')
        {
            winner = 1;
        }
        else if (x[0][0] == 'O' && x[1][1] == 'O' && x[2][2] == 'O')
        {
            winner = 2;
        }
        else if (x[2][0] == 'X' && x[1][1] == 'X' && x[0][2] == 'X')
        {
            winner = 1;
        }
        else if (x[2][0] == 'O' && x[1][1] == 'O' && x[0][2] == 'O')
        {
            winner = 2;
        }
    }
    else if (count == 9)
    {
        std::cout << "Its a draw.";
        winner = 3;
    }
    else
    {
        std::cout << "It is the next players turn\n\n";
    }
    if (winner > 0)
    {
        done = true;
    }
    return done;
}

int TicTacToe::play()       //initializes the game
{
    int done = false;
    Board* print(Board);
    while (!done)
    {
        int count = 0;
        Board* makeMove();
        Board* (Board);
        count++;
        if (count != 9)
        {
            return !done;
        }
        else
        {
            done = true;
        }
    }
    return 0;
}

int main()              //main method
{
    TicTacToe playGame;
        playGame.TtlGames = 0, playGame.TtlP1 = 0, 
            playGame.TtlP2 = 0, playGame.TtlDraws = 0;                  //counters for total games, Player 1 Total, 
    int Winner = 0;                                                     //Player 2 Total , and Total draws.

    char done = false;

    while (!done)
    {
        // This will display before each game
        std::cout << "Let's play a game of TicTacToe\n\n";

        // Play a game and remember who won (if anyone)
        playGame.intBoard();

    }

    // Finish
    std::cout << "\n\nThank you for playing!\n";
    std::cin.get();
    std::cin.get();
    return 0;
}

我尝试了 Code Fuller 的建议,但它给了我这个错误。

/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

所以我想也许如果我将 Main 方法放在一个单独的文件中并且 link 它们都可以工作。我明白了:

/tmp/ccmSwwUz.o: In function `TTTBoard::intBoard()':
TicTacToe.cpp:(.text+0x0): multiple definition of `TTTBoard::intBoard()'
/tmp/ccSwOY9D.o:Board.cpp:(.text+0x0): first defined here
/tmp/ccmSwwUz.o: In function `TTTBoard::gameState(char (*) [3])':
TicTacToe.cpp:(.text+0x104): multiple definition of `TTTBoard::gameState(char (*           ) [3])'
/tmp/ccSwOY9D.o:Board.cpp:(.text+0x288): first defined here
/tmp/ccSwOY9D.o: In function `TTTBoard::intBoard()':
Board.cpp:(.text+0xa7): undefined reference to `TTTBoard::play()'
/tmp/ccSwOY9D.o: In function `TTTBoard::makeMove()':
Board.cpp:(.text+0x176): undefined reference to `TTTBoard::turn(int)'
Board.cpp:(.text+0x19b): undefined reference to `TTTBoard::turn(int)'
/tmp/ccmSwwUz.o: In function `TTTBoard::intBoard()':
TicTacToe.cpp:(.text+0xa7): undefined reference to `TTTBoard::play()'
/tmp/ccz4019v.o: In function `main':
Main.cpp:(.text+0x48): undefined reference to `TicTacToe::intBoard()'
collect2: ld returned 1 exit status

然后我尝试先将 Board 编译成一个对象,然后 linking TicTacToe 和 Main:

g++ Board.o TicTacToe.cpp Main.cpp -o TTT

并出现以下错误:

/tmp/cc9h5kAs.o: In function `TTTBoard::intBoard()':
TicTacToe.cpp:(.text+0x0): multiple definition of `TTTBoard::intBoard()'
Board.o:Board.cpp:(.text+0x0): first defined here
/tmp/cc9h5kAs.o: In function `TTTBoard::gameState(char (*) [3])':
TicTacToe.cpp:(.text+0x104): multiple definition of `TTTBoard::gameState(char (*) [3])'
Board.o:Board.cpp:(.text+0x288): first defined here
Board.o: In function `TTTBoard::intBoard()':
Board.cpp:(.text+0xa7): undefined reference to `TTTBoard::play()'
Board.o: In function `TTTBoard::makeMove()':
Board.cpp:(.text+0x176): undefined reference to `TTTBoard::turn(int)'
Board.cpp:(.text+0x19b): undefined reference to `TTTBoard::turn(int)'
/tmp/cc9h5kAs.o: In function `TTTBoard::intBoard()':
TicTacToe.cpp:(.text+0xa7): undefined reference to `TTTBoard::play()'
/tmp/ccZlZ4Dn.o: In function `main':
Main.cpp:(.text+0x48): undefined reference to `TicTacToe::intBoard()'
collect2: ld returned 1 exit status

您试图将 Board.cpp 编译为不包含 'main' 入口点的可执行文件。你必须先编译 Board.cpp 到目标文件:

gcc Board.cpp -c

然后你可以用Board.o编译TicTacToe.cpp和link:

gcc Board.o TicTacToe.cpp -o TicTacToe