2013-03-29 21 views
31

Mi chiedevo se qualcuno potesse darmi una mano con questo - Sono solo nuovo di C++ e mi sta causando un sacco di problemi.Errore C++ 'Riferimento non definito a Class :: Function()'

Sto provando a creare oggetti di classe Deck e Card relativamente semplici.

L'errore si presenta in "Deck.cpp", dichiarazione di un array di schede, e quindi quando provo a riempire l'array con oggetti di carte. Dice che c'è un riferimento non definito a Card::Card(), Card::Card(Card::Rank, Card::Suit) e Card::~Card().

Ho tutto il mio include apparentemente giusto, quindi non so cosa sta andando male.

Il codice è il seguente:

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

risposta

26

Che cosa state usando per compilare questo? Se c'è un errore di riferimento non definito, di solito è perché il file .o (che viene creato dal file .cpp) non esiste e il tuo compilatore/sistema di compilazione non è in grado di collegarlo.

Inoltre, nel file card.cpp, la funzione deve essere Card::Card() anziché void Card. Card:: è ambito; significa che la tua funzione Card() è un membro della classe Card (che ovviamente è, dal momento che è il costruttore per quella classe). Senza questo, void Card è solo una funzione gratuita. Allo stesso modo,

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

dovrebbe essere

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

Inoltre deck.cpp, che stai dicendo #include "Deck.h" anche se lei ha fatto riferimento ad essa come deck.h. Gli include sono case sensitive.

8

Nella definizione della classe Card, una dichiarazioneper una costruzione di default appare:

class Card 
{ 
    // ... 

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

    // ... 
}; 

Ma non corrispondente definizione è dato. In realtà, questa definizione di funzione (da card.cpp):

void Card() { 
//nothing 
} 

Does non definire un costruttore, ma piuttosto una funzione globale chiamata Card che restituisce void. Probabilmente significava scrivere questo, invece:

Card::Card() { 
//nothing 
} 

A meno che non hai fatto, dal momento che il costruttore di default è dichiarata ma non definiti, il linker produrrà errore sui riferimenti non definiti quando viene trovata una chiamata al costruttore di default.


Lo stesso si applica al costruttore che accetta due argomenti. Questo:

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

devono essere riscritti in questo:

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

E lo stesso vale anche per altre funzioni membro: a quanto pare non è stato aggiunto il qualificatore Card:: prima che i nomi delle funzioni associate in loro definizioni. Senza di esso, tali funzioni sono funzioni globali piuttosto che definizioni di funzioni membro.


Il distruttore, d'altra parte, è dichiarato ma mai definito.Basta fornire una definizione per questo in card.cpp:

Card::~Card() { } 
+0

Tutte le definizioni di funzione devono essere come questa, nel file CPP? ad es. Card :: Rank Card :: GetRank() { return cardRank; } Card :: Suit Card :: GetSuit() { carta di ritorno Tuta; } –

+1

@BenHarris: Sì, è così che si definiscono le funzioni membro –

0

Specificare la scheda Class per il constructor-:

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

E anche definire il costruttore e distruttore di default.

3

Questa parte ha problemi:

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 è un array dinamico, ma non un membro della classe Card. È strano se si desidera inizializzare un array dinamico che non è membro della classe
  2. void Deck() non è costruttore di class deck poiché si è perso l'operatore di risoluzione dell'ambito . Potresti essere confuso con la definizione del costruttore e della funzione con il nome Deck e il tipo di ritorno void.
  3. nei loop, è necessario utilizzare < non > altrimenti, il ciclo non sarà mai eseguito .
Problemi correlati