error LNK2019: 未解析的外部符号

11

最近我又开始学习C++编程,为了学习目的,我正在尝试创建一个扑克游戏。但奇怪的是,我一直遇到以下错误:

1>LearningLanguage01.obj : error LNK2019: unresolved external symbol "public: __thiscall PokerGame::Poker::Poker(void)" (??0Poker@PokerGame@@QAE@XZ) referenced in function "void __cdecl `dynamic initializer for 'pokerGame''(void)" (??__EpokerGame@@YAXXZ)
1>LearningLanguage01.obj : error LNK2019: unresolved external symbol "public: __thiscall PokerGame::Poker::~Poker(void)" (??1Poker@PokerGame@@QAE@XZ) referenced in function "void __cdecl `dynamic atexit destructor for 'pokerGame''(void)" (??__FpokerGame@@YAXXZ)
1>LearningLanguage01.obj : error LNK2019: unresolved external symbol "public: void __thiscall PokerGame::Poker::begin(void)" (?begin@Poker@PokerGame@@QAEXXZ) referenced in function _wmain
1>C:\Visual Studio 2012\Projects\LearningLanguage01\Debug\LearningLanguage01.exe : fatal error LNK1120: 3 unresolved externals

我已经就这个问题进行了一些研究,大多数指向头文件和 .cpp 文件中构造函数和析构函数定义不匹配。但我没有看到头文件和 .cpp 文件有任何问题。

这是 poker.h 的代码:

#pragma once

#include "Deck.h"

using namespace CardDeck;

namespace PokerGame
{
    const int MAX_HAND_SIZE = 5;

    struct HAND
    {
        public:
            CARD cards[MAX_HAND_SIZE];
    };

    class Poker
    {
        public:
            Poker(void);
            ~Poker(void);
            HAND drawHand(int gameMode);
            void begin();
    };
}

并且在 .cpp 文件中的代码:

#include "stdafx.h"
#include "Poker.h"

using namespace PokerGame;

const int TEXAS_HOLDEM = 0;
const int FIVE_CARD = 1;

class Poker
{
    private:
        Deck deck;      

    Poker::Poker()
    {
        deck = Deck();
    }

    Poker::~Poker()
    {
    }

    void Poker::begin()
    {
        deck.shuffle();
    }

    //Draws a hand of cards and returns it to the player
    HAND Poker::drawHand(int gameMode)
    {
        HAND hand;

        if(gameMode == TEXAS_HOLDEM)
        {
            for(int i = 0; i < sizeof(hand.cards); i++)
            {
                hand.cards[i] = deck.drawCard();
            }
        }

        return hand;
    }

};

5
你只能定义你的类一次。在cpp文件中,去掉class Poker {...}这一层。 - chris
我必须说,我从未见过有人这样做,因此我怀疑该特定问题在网站上没有其他地方。 - chris
@chris 或许你可以把那个作为一个答案。这样就不会显得没有解决了。 - Bart
@Bart,我想我可以。实际上,原帖已经有答案了,但是它被删除了。 - chris
@chris 哦,我这里只有不到10k,所以看不到那个。不过还是谢谢。 - Bart
2个回答

8
由于下面的评论,我重写了之前的内容。
链接器报错的问题是您已经在 Poker 中声明了成员函数,但没有定义它们。这是怎么回事?首先,您创建了一个新类,并在其中定义了单独的成员函数。
您的头文件 Poker 类存在于 PokerGame 命名空间中,而您的 cpp 文件 Poker 类存在于全局命名空间中。为了解决这个问题,请将它们放在同一个命名空间中:
//cpp file
namespace PokerGame {
    class Poker {
        ...
    };
}

既然它们在同一个命名空间中,你就会遇到另一个问题。你正在类体内定义成员函数,但是不是第一个函数。这些定义不能放在同名的类体中。将cpp文件中的整个类删除:

现在他们在同一名称空间中,所以您还有另一个问题。您正在类体内定义成员函数,但不是第一个函数。这些定义不能放在同名的类体中。将cpp文件中的整个类删除:
//cpp file
namespace PokerGame {
    Poker::Poker() {
        deck = Deck(); //consider a member initializer instead
    }

    //other definitions
}

最后一件事:您将类的私有部分放错了位置。它在我们刚刚删除的那个 cpp 文件类中。它应该与类的其他部分放在一起:

//header file
namespace PokerGame {
    class Poker {
    public:
        //public stuff

    private: 
        Deck deck; //moved from cpp file
   };
}

实际上,问题在于存在两个不同的Poker类。头文件中的那个位于PokerGame命名空间内。cpp文件中的那个则位于全局命名空间内。PokerGame命名空间内的那个被声明但从未定义,这就是为什么会出现“无法解析的外部”错误。(如果它被多次定义,你将会得到一个“多重定义”错误。) - Raymond Chen
@RaymondChen,哇,我没有仔细看过它,因为已经过去了几个月,但我刚刚注意到了更多。deck甚至不在头文件中,我本来想在我的答案中提到命名空间,但完全错过了示例中的一个。谢谢。 - chris
@RaymondChen,我重新写了它。这比尝试改变/合并那么多错误/新信息要容易得多。希望我现在没有漏掉任何东西。 - chris

0
另一个解决方案可能是:检查cmake文件,确保它(例如在ADD_EXECUTABLE中)包括您列出的.cpp文件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接