oop-C ++错误“对Class :: Function()的未定义引用”

这个问题已经在这里有了答案:

  • 什么是未定义的引用/未解决的外部符号错误,如何解决?                                     32个答案

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

我试图使相对简单的Deck和Card类对象。

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

我拥有的所有看似正确的东西,所以我不知道出了什么问题。

代码如下:

卡座

#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

卡组

#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();

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

#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;
}
Ben Harris asked 2020-01-11T03:19:29Z
4个解决方案
46 votes

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

另外,在您的card.cpp中,该功能应为#include "Deck.h",而不是void Card。 这意味着您的Card()函数是Card类的成员(显然是Card类的成员,因为它是该类的构造函数)。 没有这个,空卡就只是一个免费功能。 同样,

#include "Deck.h"

应该

#include "Deck.h"

另外,即使您将其称为deck.h,在deck.cpp中也要说出#include "Deck.h"。 包括区分大小写。

maditya answered 2020-01-11T03:20:12Z
11 votes

card.cpp类的定义中,将显示默认构造的声明:

class Card
{
    // ...

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

    // ...
};

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

void Card() {
//nothing
}

没有定义构造函数,而是定义了一个名为card.cpp的全局函数,该函数返回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.cpp限定符。 没有它,这些函数将是全局函数,而不是成员函数的定义。


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

Card::~Card() { }
Andy Prowl answered 2020-01-11T03:21:04Z
3 votes

这部分有问题:

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. <是动态数组,但不是>类的成员。 如果您要初始化不是该类成员的动态数组,这很奇怪
  2. <不是Deck类的构造函数,因为您错过了范围解析运算符。 您可能对定义名称为>并返回类型void的构造函数和函数感到困惑。
  3. 在循环中,您应该使用<而不是>,否则,循环永远不会被执行。
taocp answered 2020-01-11T03:21:38Z
1 votes

指定构造函数的类卡:

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

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

suspectus answered 2020-01-11T03:22:03Z
translate from https://stackoverflow.com:/questions/15712821/c-error-undefined-reference-to-classfunction