【问题标题】:C++ error 'Undefined reference to Class::Function()' [duplicate]C ++错误'对Class :: Function()的未定义引用'[重复]
【发布时间】:2013-03-20 17:16:35
【问题描述】:

我想知道是否有人可以帮助我解决这个问题 - 我只是 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

deck.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

card.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;
}

【问题讨论】:

    标签: c++ oop undefined


    【解决方案1】:

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

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

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

    应该是

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

    此外,在deck.cpp 中,您说的是#include "Deck.h",即使您将其称为deck.h。包含区分大小写。

    【讨论】:

      【解决方案2】:

      Card 类的定义中,出现了一个默认构造的声明

      class Card
      {
          // ...
      
          Card(); // <== Declaration of default constructor!
      
          // ...
      };
      

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

      void Card() {
      //nothing
      }
      

      定义构造函数,而是定义一个名为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() { }
      

      【讨论】:

      • CPP 文件中的所有函数定义都必须是这样吗?例如Card::Rank Card::GetRank() { return cardRank; } Card::Suit Card::GetSuit() { return cardSuit; }
      • @BenHarris:是的,这就是你定义成员函数的方式
      【解决方案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 类的构造函数,因为您错过了 范围解析运算符。您可能会对使用名称 Deck 和返回类型 void 定义构造函数和函数感到困惑。
      3. 在你的循环中,你应该使用&lt; 而不是&gt; 否则,循环永远不会 被执行。

      【讨论】:

        【解决方案4】:

        为构造函数指定Class Card-:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-09-16
          • 1970-01-01
          相关资源
          最近更新 更多