2013-03-29 22 views
31

Zastanawiam się, czy ktoś może mi pomóc z tym - Jestem tylko nowy w C++ i powoduje mi to sporą ilość problemów.Błąd C++ "Niezdefiniowane odniesienie do klasy :: Funkcja()"

Próbuję wykonać względnie proste obiekty klasy Deck i Card.

Błąd pojawia się w "Deck.cpp", deklaracja tablicy kart, a następnie, gdy próbuję wypełnić tablicę obiektami kart. Mówi, że jest niezdefiniowane odniesienie do , Card::Card(Card::Rank, Card::Suit) i .

Mam wszystkie pozornie słuszne elementy, więc nie wiem, co jest nie tak.

Kod jest w następujący sposób:

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

Odpowiedz

26

Co używasz do kompilacji to? Jeśli istnieje nieokreślony błąd odniesienia, zwykle dzieje się tak, ponieważ plik .o (tworzony z pliku .cpp) nie istnieje, a system kompilatora/kompilacji nie może go powiązać.

Również w twoim card.cpp, funkcja powinna być Card::Card() zamiast void Card. Card:: jest określania zakresu; oznacza to, że twoja funkcja Card() jest członkiem klasy Card (oczywiście, ponieważ jest to konstruktor dla tej klasy). Bez tego, void Card jest po prostu darmową funkcją. Podobnie

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

powinny być

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

Również w deck.cpp, mówisz #include "Deck.h" nawet jeśli o niej jako deck.h. Obejmuje to wielkość liter.

8

W definicji klasy Card, deklaracji dla domyślnej budowy pojawia:

class Card 
{ 
    // ... 

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

    // ... 
}; 

Ale nie odpowiada definicję wypowiedzenia. W rzeczywistości, ta definicja funkcji (z card.cpp):

void Card() { 
//nothing 
} 

Czy nie zdefiniować konstruktor, ale raczej globalna funkcja nazywa Card zwracającą void. Prawdopodobnie oznaczało to zamiast pisać:

Card::Card() { 
//nothing 
} 

ile to zrobić, ponieważ konstruktor domyślny jest zadeklarowana, ale nie określono, łącznik będzie produkować błąd o referencje niezdefiniowanych gdy znajduje się wezwanie do domyślnego konstruktora.


To samo dotyczy konstruktora akceptującego dwa argumenty. To:

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

powinno być zapisane w tym:

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

I to samo odnosi się również do innych funkcji składowych: wydaje się, że nie dodać Card:: kwalifikator przed nazwami funkcji składowych w ich definicjach. Bez niej funkcje te są funkcjami globalnymi, a nie definicjami funkcji składowych.


Z drugiej strony Twój destruktor jest zadeklarowany, ale nigdy nie zdefiniowany.Wystarczy podać definicję dla niego w card.cpp:

Card::~Card() { } 
+0

Czy wszystkie definicje funkcji muszą być w ten sposób, w pliku CPP? np. Karta :: Ranking kart :: Getränk() {return cardRank ; } karty :: karty kolorze :: GetSuit() { powrotu cardSuit; } –

+1

@BenHarris: Tak, w ten sposób definiujesz funkcje członkowskie –

0

Określ karcie zajęć dla constructor-:

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

A także określenie domyślnego konstruktora i destruktora.

3

Ta część ma problemy:

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 to dynamiczna tablica, ale nie jest członkiem Card klasie. Dziwne, jeśli chcesz zainicjować dynamiczną tablicę, która nie jest członkiem klasy, nie jest konstruktorem klasy Deck, ponieważ pominąłeś operator zakresu rozdzielczości . Możesz być mylone z definiowania konstruktora i funkcja o nazwie Deck i powrotnych typu void.
  2. w twoich pętlach, powinieneś użyć < nie > w przeciwnym razie pętla nigdy nie będzie wykonana .
Powiązane problemy