2013-03-29 34 views
31

我想知道是否有人可以幫我解決這個問題 - 我只是C++的新手,它給我帶來了相當多的麻煩。C++錯誤'未定義的引用Class :: Function()'

我試圖做出相對簡單的甲板和卡類對象。

錯誤顯示在「Deck.cpp」中,聲明一個卡片數組,然後當我嘗試用卡片對象填充數組時。它說有一個未定義的參考Card::Card(),Card::Card(Card::Rank, Card::Suit)Card::~Card()

我已經把我的所有包括看起來都是正確的,所以我不知道發生了什麼問題。

的代碼如下:

加入deck.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(); 

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

回答

26

你在使用編譯這個?如果存在未定義的引用錯誤,通常是因爲.o文件(它是從.cpp文件創建的)不存在,並且您的編譯器/編譯系統無法鏈接它。

另外,在您的card.cpp中,函數應該是Card::Card()而不是void CardCard::範圍;這意味着你的函數是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.包括區分大小寫。

8

在你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() { } 
+0

在CPP文件中,所有的函數定義都必須像這樣嗎? 例如 Card :: Rank Card :: GetRank(){ return cardRank; } Card ::西服卡:: GetSuit(){ return cardSuit; } –

+1

@BenHarris:是的,那是你如何定義成員函數 –

0

指定的constructor-類卡:

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

,還可以定義默認構造函數和析構函數。

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類的成員。如果你想初始化一個不是類的成員的動態數組,這很奇怪,因爲你錯過了 作用域解析運算符,所以它不是類Deck的構造函數。您可能會混淆定義名稱爲Deck的構造函數和函數,返回類型void。在你的循環
  2. ,你應該使用<>否則,循環將永遠 被執行。