87

我想知道是否有人可以帮助我解决这个问题 - 我只是 C++ 的新手,这给我带来了很多麻烦。

我正在尝试制作相对简单的 Deck 和 Card 类对象。

错误出现在“Deck.cpp”中,声明了一组卡片,然后当我尝试用卡片对象填充数组时。它说有一个未定义的引用Card::Card(),Card::Card(Card::Rank, Card::Suit)Card::~Card()

我的所有内容似乎都是正确的,所以我不知道出了什么问题。

代码如下:

甲板.h

#ifndef DECK_H
#define DECK_H
#include "card.h"

class Deck
{
 public:
    Deck();
    ~Deck();
    Card DealNextCard();
    void Shuffle();
    void DisplayDeck();
protected:
private:

};

#endif // DECK_H

甲板.cpp

#include "Deck.h"
#include "card.h"

using namespace std;

const int NUM_TOTAL_CARDS = 52;
const int NUM_SUITS = 4;
const int NUM_RANKS = 13;
Card* cardArray;
void Deck() {
    cardArray = new Card[NUM_TOTAL_CARDS];
    int cardCount = 0;
    for (int i = 0; i > NUM_SUITS; i++) {
        for (int j = 0; j > NUM_RANKS; j++) {
            cardArray[cardCount] = Card(Card::Rank(i), Card::Suit(j) );
            cardCount++;
        }
    }
}


Card DealNextCard();
void Shuffle();
void DisplayDeck();

卡.h

class Card
{

    public:
        enum Suit {D=0, H, C, S};
        enum Rank {ONE=0, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, J, Q, K, A};
        Card(Card::Rank, Card::Suit);
        Card();
        virtual ~Card();
        Card::Suit suit;
        Card::Rank rank;
        Card::Rank GetRank();
        Card::Suit GetSuit();
        std::string CardName();

    protected:

    private:

};

#endif // CARD_H

卡片.cpp

#include "card.h"
using namespace std;


Card::Suit cardSuit;
Card::Rank cardRank;

void Card() {
    //nothing
     }


void Card(Card::Rank rank, Card::Suit suit) {
cardRank = rank;
cardSuit = suit;
}

Card::Rank GetRank() {
return cardRank;
}
Card::Suit GetSuit() {
return cardSuit;
}
std::string CardName() {
    string test;
    test = "testing string";
    return test;
}
4

4 回答 4

82

What are you using to compile this? If there's an undefined reference error, usually it's because the .o file (which gets created from the .cpp file) doesn't exist and your compiler/build system is not able to link it.

Also, in your card.cpp, the function should be Card::Card() instead of void Card. The Card:: is scoping; it means that your Card() function is a member of the Card class (which it obviously is, since it's the constructor for that class). Without this, void Card is just a free function. Similarly,

void Card(Card::Rank rank, Card::Suit suit)

should be

Card::Card(Card::Rank rank, Card::Suit suit)

Also, in deck.cpp, you are saying #include "Deck.h" even though you referred to it as deck.h. The includes are case sensitive.

于 2013-03-29T23:21:25.737 回答
13

在您的Card类的定义中,出现了默认构造的声明:

class Card
{
    // ...

    Card(); // <== Declaration of default constructor!

    // ...
};

但没有给出相应的定义。其实这个函数定义(来自card.cpp):

void Card() {
//nothing
}

不定义构造函数,而是定义一个名为 return 的全局Card函数void。您可能打算改为这样写:

Card::Card() {
//nothing
}

除非您这样做,因为默认构造函数已声明但未定义,当找到对默认构造函数的调用时,链接器将产生有关未定义引用的错误。


这同样适用于接受两个参数的构造函数。这:

void Card(Card::Rank rank, Card::Suit suit) {
    cardRank = rank;
    cardSuit = suit;
}

应该改写成这样:

Card::Card(Card::Rank rank, Card::Suit suit) {
    cardRank = rank;
    cardSuit = suit;
}

这同样适用于其他成员函数:似乎您没有Card::在其定义中的成员函数名称之前添加限定符。没有它,这些函数是全局函数,而不是成员函数的定义。


另一方面,您的析构函数已声明但从未定义。只需为它提供一个定义card.cpp

Card::~Card() { }
于 2013-03-29T23:14:15.293 回答
3

这部分有问题:

Card* cardArray;
void Deck() {
    cardArray = new Card[NUM_TOTAL_CARDS];
    int cardCount = 0;
    for (int i = 0; i > NUM_SUITS; i++) {  //Error
        for (int j = 0; j > NUM_RANKS; j++) { //Error
            cardArray[cardCount] = Card(Card::Rank(i), Card::Suit(j) );
            cardCount++;
         }
    }
 }
  1. cardArray是一个动态数组,但不是Card类的成员。如果您想初始化一个不是该类成员的动态数组,这很奇怪
  2. void Deck()不是类 Deck 的构造函数,因为您错过了范围解析运算符。您可能会对使用 nameDeck和 return type定义构造函数和函数感到困惑void
  3. 在你的循环中,你不应该使用<>否则循环将永远不会被执行。
于 2013-03-29T23:21:03.047 回答
1

为构造函数指定类卡-:

void Card::Card(Card::Rank rank, Card::Suit suit) {

并且还定义了默认的构造函数和析构函数。

于 2013-03-29T23:14:43.343 回答