关于oop:C ++错误’对类的未定义引用:: Function()

C++ error 'Undefined reference to Class::Function()'

本问题已经有最佳答案,请猛点这里访问。

我想知道有没有人能帮我解决这个问题——我只是个C++新手,这给我带来了很多麻烦。

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

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

我所有的东西看起来都是对的,所以我不知道出了什么问题。

代码如下:

甲板上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#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

德克普

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#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();

贺卡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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

卡普

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#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;
}

你用什么来编译这个?如果存在未定义的引用错误,通常是因为.o文件(从.cpp文件创建)不存在,并且编译器/生成系统无法链接它。

另外,在card.cpp中,函数应该是Card::Card(),而不是void CardCard::是作用域;这意味着你的Card()函数是card类的成员(显然是,因为它是该类的构造函数)。没有这个,作废卡只是一个免费的功能。同样地,

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

应该是

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

另外,在deck.cpp中,您说的是#include"Deck.h",尽管您将其称为deck.h。includes是区分大小写的。


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

1
2
3
4
5
6
7
8
class Card
{
    // ...

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

    // ...
};

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

1
2
3
void Card() {
//nothing
}

不定义构造函数,而是定义一个名为Card的全局函数,该函数返回void。你可能想写这个:

1
2
3
Card::Card() {
//nothing
}

除非这样做,否则由于默认构造函数是声明的,但没有定义,当找到对默认构造函数的调用时,链接器将产生有关未定义引用的错误。

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

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

应重写为:

1
2
3
4
Card::Card(Card::Rank rank, Card::Suit suit) {
    cardRank = rank;
    cardSuit = suit;
}

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

另一方面,析构函数是声明的,但从未定义。只需在card.cpp中为其提供一个定义:

1
Card::~Card() { }


本部分存在问题:

1
2
3
4
5
6
7
8
9
10
11
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++;
         }
    }
 }
  • cardArray是一个动态数组,但不是Card类的成员。如果您想初始化一个不是类成员的动态数组,这很奇怪
  • void Deck()不是类deck的构造函数,因为您错过了作用域解析运算符。您可能会混淆如何定义名为Deck和返回类型为void的构造函数和函数。
  • 在循环中,应该使用<而不是>,否则循环将永远不会被处决。

  • 指定构造函数的类卡-:

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

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