未定义引用(main.cpp 文件中出现错误)

Undefined Reference to (error coming in main.cpp file)

在 Code::Blocks 中尝试编译我的代码时,我收到一堆未定义的引用错误。代码如下。

Header

#ifndef BLACKJACK_GAME
#define BLACKJACK_GAME

// A game of blackjack has a deck and two hands
#include "Deck.h"
#include "BlackjackHand.h"

// Different ways the game can end.  The first states take precedence over
// over the latter states so check for the early ones first (like blackjack)!
// Note that a "natural 21" is when you are delt two cards totaling 21.
enum eGameState {
    GAME_BLACKJACK_PUSH,    // Both player and dealer have a natural 21
    GAME_DEALER_BLACKJACK,  // Dealer has a natural 21
    GAME_PLAYER_BLACKJACK,  // Player has a natural 21
    GAME_DEALER_BUST,       // The dealer has more than 21
    GAME_PLAYER_BUST,       // The player has more than 21
    GAME_DEALER_WIN,        // The dealer's score is higher than players
    GAME_PLAYER_WIN,        // The player's score is higher than dealers
    GAME_PUSH               // The scores are tied
};

class BlackjackGame
{
public:
    BlackjackGame();

    // Clear the players hands and shuffle the deck
    void newGame();

    // Play a single round of blackjack showing the output using
    // the 'PDcurses' library (for color and card suits).
    void playGameCurses();

    // Display the deck on the screen (for debugging purposes)
    void printDeckCurses();

    // Print both players hands to the screen using 'PDCurses'
    // If pShowDealerScore is true then the dealer's score is printed
    // Otherwise, the dealer's score is shown as '??'
    void printHandsCurses(bool pShowDealerScore = false) const;

    // Determine the state of the game.  Note that if you have not yet
    // played a round since you constructed this object or called newGame()
    // Then the state returned is not accurate.
    eGameState getGameState() const;

private:
    // A deck of cards for shufflying and dealing hands
    Deck mDeck;

    // The two hands for the player and the dealer
    BlackjackHand mPlayer, mDealer;

    // A helper function for prompting the player (internal use only)
    char promptPlayerCurses();

    // A helper function to quit the game (internal use only)
    void quitGameCurses();
};

#endif

CPP

#include "BlackjackGame.h"

// The library used for our text based user interface
#include <curses.h>

// Normal text color for PDCurses (defined in main)
#define NORM_TEXT   1

// Default constructor (does nothing)
BlackjackGame::BlackjackGame() {}

/* newGame() - Clear the two hands so we are ready for a new game */
void BlackjackGame::newGame()
{
    mDealer.clear();
    mPlayer.clear();
}

/* playGameCurses() - Play a single round of poker with one human player and one
 * dealer following standard Vegas rules.  Uses PDCurses for input and output to
 * the console.
 *
 * You must implement this method but you do not need to worry about curses.  Call
 * 'promptPlayerCurses() to show the hands and prompt the human player to hit, stand
 * or quit.  This method will return the key they pressed.  You can also use
 * quitGameCurses() to exit properly if the user chose to 'quit'.
 */
void BlackjackGame::playGameCurses()
{
    // TODO: Shuffle the deck and deal the cards (make sure dealer's first card is hidden).
    mDeck.shuffle();

    mPlayer.takeCard(mDeck.dealCard());
    mDealer.takeCard(mDeck.dealCard());
    mDealer.hideCard();
    mPlayer.takeCard(mDeck.dealCard());
    mDealer.takeCard(mDeck.dealCard());



    // TODO: Check for a 'natural 21' (blackjack) before playing

    if ( mDealer.hasBlackjack() || mPlayer.hasBlackjack())
        quitGameCurses();

    // TODO: Allower human player to hit, stand and quit as needed (repeat until player is done)

    int flag = 0;

    while(flag!=1)
    {
        char input = promptPlayerCurses();  // This line is an example only, a placeholder

        switch(input)
        {
            case 'h': mPlayer.takeCard(mDeck.dealCard());
                  break;
            case 's': flag =1;
                     break;

            case 'q': quitGameCurses();
                    break;
            default: break;

        }
    }
    // TODO: Play the 'dealer' hand according to vegas rules

    mDealer.showCards();

    while(vegasDealerWouldHit())
    {
        mDealer.takeCard(mDeck.dealCard());

    }

}

/* promptPlayerCurses() - Show the hands and prompt the human player to hit, stand or quit.
 * output: returns the single character entered by the player at the prompt.
 *    - 'h' means hit, 's' means stand
 *    - 'q' means you should immediatly quit (call 'quitGameCurses()')
 */
char BlackjackGame::promptPlayerCurses()
{
    // Show the hands
    printHandsCurses();

    // Hit or stand?
    attron(COLOR_PAIR(NORM_TEXT));
    mvprintw(3, 0, "Hit, stand or Quit ('h', 's', 'q'): ");
    refresh();

    // Read and return a single character
    return getch();
}

/* quitGameCurses() - End curses output and exit the program immediately */
void BlackjackGame::quitGameCurses()
{
    // End curses output, then pause and exit
    endwin();
    system("pause");
    exit(0);
}

/* printDeckCurses() - A handy function that displays the content of the game deck
 * using curses.
 *
 * This can be handy for debugging your deck and making sure it is getting properly
 * shuffled.  It is presently used for the fancy opening screen.
 */
void BlackjackGame::printDeckCurses()
{
    // Start at the upper left corner of the screen
    move(0, 0);

    // For all 52 cards
    for(int i=1; i<=52; i++)
    {
        // Get the next card and print it
        PrintableCard lCard = mDeck.dealCard();
        lCard.printCurses();

        // If we've output 13 cards then move down a row
        if(i%13 == 0)
        {
            move(2*(i/13), 0);
        }
        else
        {
            // Switch back to normal text color and output ' ' characters
            attron(COLOR_PAIR(NORM_TEXT));
            if(lCard.getFaceValue() == VALUE_TEN) printw(" ");
            else printw("  ");
        }
    }
}

/* printHandsCurses() - A function to display the current scores and hands for this game
 * using curses.
 *
 * This function is used in promptPlayerCurses() to show the hands before asking them if
 * they want to hit or stand.  Note that it alsways clears the window before drawing.
 */
void BlackjackGame::printHandsCurses(bool pShowDealerScore) const
{
    // Clear window
    erase();

    // Show dealer and player hands
    attron(COLOR_PAIR(NORM_TEXT));
    mvprintw(0, 0, "Player: %d\n", mPlayer.score());
    move(1, 0); mPlayer.printCurses();

    attron(COLOR_PAIR(NORM_TEXT));
    if(pShowDealerScore)
    {
        mvprintw(0, 50, "Dealer: %d\n", mDealer.score());
    }
    else
    {
        mvprintw(0, 50, "Dealer: ??\n");
    }
    move(1, 50); mDealer.printCurses();

    refresh();
}

/* getGameStat() - Examine the hands of both players and return the current state of
 * the game using the eGameState enum.
 *
 * You must examine the state of the game by comparing the two hands (their scores and their
 * number of cards) and return the appropriate constant from the eGameState enum.  Assume
 * that the game is over (i.e. the player and dealer have both either gone bust or decided
 * to stand).
 */
eGameState BlackjackGame::getGameState() const
{

    if(mDealer.hasBlackjack() && mPlayer.hasBlackjack())
    {
        return GAME_BLACKJACK_PUSH;
    }
    else if(mDealer.hasBlackjack())
    {
        return GAME_DEALER_BLACKJACK;
    }
    else if(mPlayer.hasBlackJack())
    {
        return GAME_PLAYER_BLACKJACK;
    }
    else if(mPlayer.score() > 21)
    {
        return GAME_PLAYER_BUST;
    }
    else if(mDealer.score() > 21)
    {
        return GAME_DEALER_BUST;
    }
    else if(mDealer.score() > mPlayer.score())
    {
        return GAME_DEALER_WIN;
    }
    else if(mDealer.score() < mPlayer.score())
    {
        return GAME_PLAYER_WIN;
    }
    else {
        return GAME_PUSH;
    }

    }
}

主要

#include <cstdlib>
#include <iostream>     // Standard input and output
#include <string>
using namespace std;

#include <curses.h>
#include "BlackjackGame.h"

// Three different types of text colors used with PDCurses
#define NORM_TEXT   1
#define WIN_TEXT    2
#define LOSE_TEXT   3

int main()

    {
        // Setup 'PDcurses'
        initscr();
        start_color();

        // Define our colors text colors (foreground, background)
        init_pair(NORM_TEXT, COLOR_WHITE, COLOR_BLACK);
        init_pair(WIN_TEXT, COLOR_YELLOW, COLOR_BLACK);
        init_pair(LOSE_TEXT, COLOR_RED, COLOR_BLACK);

        // Define our card colors (these are declared in PrintableCard.h)
        init_pair(BLACK_CARD, COLOR_BLACK, COLOR_WHITE);
        init_pair(RED_CARD, COLOR_RED, COLOR_WHITE);

        // Input from the user and a game object
        char ch = '[=13=]';
        BlackjackGame myGame;

        // Output a 'fancy' welcome screen
        myGame.printDeckCurses();
        attron(COLOR_PAIR(WIN_TEXT));
        mvprintw(1, 13, "Welcome to Blackjack!");
        mvprintw(5, 11, "Press any key to play ...");
        refresh();

        // Wait for input (the 'press any key to begin' thing)
        ch = getch();

        // Back to normal text to start the game
        attron(COLOR_PAIR(NORM_TEXT));

        do // Loop to play a new game until the user exits
        {
            // Restart and play a game (using curses)
            myGame.newGame();

            // Play a round of blackjack (most of the magic happens here!)
            myGame.playGameCurses();

            // Print the final status of the game
            myGame.printHandsCurses(true);

            // Print a game results message (use BOLD and the appropriate text color)
            attron(A_BOLD);
            switch(myGame.getGameState())
            {
                case GAME_BLACKJACK_PUSH:
                    attron(COLOR_PAIR(WIN_TEXT));
                    mvprintw(10, 25, "BLACKJACK TIE!!");
                break;

                case GAME_DEALER_BLACKJACK:
                    attron(COLOR_PAIR(LOSE_TEXT));
                    mvprintw(10, 25, "Dealer Blackjack. You lose.");
                break;

                case GAME_PLAYER_BLACKJACK:
                    attron(COLOR_PAIR(WIN_TEXT));
                    mvprintw(10, 25, "BLACKJACK! You win!");
                break;

                case GAME_DEALER_BUST:
                    attron(COLOR_PAIR(WIN_TEXT));
                    mvprintw(10, 25, "Dealer Bust. You Win!");
                break;
                case GAME_PLAYER_BUST:
                    attron(COLOR_PAIR(LOSE_TEXT));
                    mvprintw(10, 25, "BUST. You lose.");
                break;

                case GAME_DEALER_WIN:
                    attron(COLOR_PAIR(LOSE_TEXT));
                    mvprintw(10, 25, "You lose.");
                break;

                case GAME_PLAYER_WIN:
                    attron(COLOR_PAIR(WIN_TEXT));
                    mvprintw(10, 25, "You Win!");
                break;

                case GAME_PUSH:
                    attron(COLOR_PAIR(WIN_TEXT));
                    mvprintw(10, 25, "It's a tie!");
                break;
            }

            // Turn off bold and return to normal text color
            attroff(A_BOLD);
            attron(COLOR_PAIR(NORM_TEXT));

            // Prompt user to play again
            mvprintw(20, 0, "Play again (y/n): ");
            refresh();
            ch = getch();
        } while(ch != 'n');

        // Close out 'PDCurses' and pause before exiting
        endwin();
        system("pause");
        return 0;
    }

在这个程序中,我尝试创建游戏 BlackJack,大部分游戏都在其他文件中,但我没有收到其他文件中的错误。错误来自 Main 内部的代码。错误是

undefined reference to `BlackjackGame::blackjackGame()

undefined reference to `BlackjackGame::printDeckCurses()

undefined reference to `BlackjackGame::newGame()

undefined reference to `BlackjackGame::playGameCurses()

undefined reference to `BlackjackGame::printedHandsCurses()

undefined reference to `BlackjackGame::getGameState()

由于所有这些错误都来自 main 和 header 中的这些引用,这一定是我的问题,将两者联系起来。对吗?

这个问题告诉您,当您构建可执行文件或库时,您没有 link 在 BlackjackGame.o 目标文件中。

为了通过 linking 阶段,您必须将此文件中的 Makefile 修改为 link。

编辑: 查看您如何使用 Codeblocks 进行编译,检查这些 links(因为此错误消息在不同的编译器中意味着不同的事情):

undefined reference to function code blocks

Code::Blocks 10.05 Undefined reference to function

根据 link 2

中的答案,您似乎需要将 BlackJackGame.cpp 添加到您的项目中

转到 Project/Add 文件将 BlackJackGame 源文件添加到您的项目,然后重新构建,这应该可以工作