web-dev-qa-db-fra.com

Erreur C ++ 'Référence non définie à Class :: Function ()'

Je me demandais si quelqu'un pourrait m'aider avec ceci - je ne suis qu'un débutant en C++ et cela me cause pas mal de problèmes.

J'essaie de créer des objets de classe Deck et Card relativement simples.

L'erreur apparaît dans "Deck.cpp", déclaration d'un tableau de cartes, puis lorsque j'essaie de remplir le tableau avec des objets de carte. Il y a une référence non définie à Card::Card(), Card::Card(Card::Rank, Card::Suit) et Card::~Card().

J'ai apparemment tous mes éléments inclus, alors je ne sais pas ce qui ne va pas.

Le code est comme suit:

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;
}
52
Ben Harris

Qu'est-ce que vous utilisez pour compiler cela? S'il existe une erreur de référence non définie, c'est généralement parce que le fichier .o (créé à partir du fichier .cpp) n'existe pas et que votre système de compilation/compilation n'est pas en mesure de le lier.

De plus, dans votre card.cpp, la fonction devrait être Card::Card() au lieu de void Card. Le Card:: est portée; cela signifie que votre fonction Card() est membre de la classe Card (ce qui est évidemment le cas, car il s'agit du constructeur de cette classe). Sans cela, void Card n’est qu’une fonction gratuite. De même,

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

devrait être

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

De plus, dans deck.cpp, vous dites #include "Deck.h" même si vous l'avez appelé deck.h. Les includes sont sensibles à la casse.

46
maditya

Dans la définition de votre classe Card, une déclaration pour une construction par défaut apparaît:

class Card
{
    // ...

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

    // ...
};

Mais aucune définition correspondante n'est donnée. En fait, cette définition de fonction (de card.cpp):

void Card() {
//nothing
}

Est-ce que pas définit un constructeur, mais plutôt une fonction globale appelée Card qui renvoie void. Vous vouliez probablement écrire ceci à la place:

Card::Card() {
//nothing
}

À moins que vous ne le fassiez, étant donné que le constructeur par défaut est déclaré mais non défini, l’éditeur de liens générera une erreur concernant les références non définies lorsqu’un appel au constructeur par défaut sera trouvé.


La même chose s'applique à votre constructeur acceptant deux arguments. Cette:

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

Devrait être réécrit dans ceci:

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

Et il en va de même pour les autres fonctions membres: il semble que vous n’ayez pas ajouté le qualificatif Card:: avant les noms de fonctions membres dans leurs définitions. Sans lui, ces fonctions sont des fonctions globales plutôt que des définitions de fonctions membres.


Votre destructeur, en revanche, est déclaré mais jamais défini. Fournissez-en une définition dans card.cpp:

Card::~Card() { }
10
Andy Prowl

Cette partie a des problèmes:

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 est un tableau dynamique, mais n'est pas membre de la classe Card. Il est étrange de vouloir initialiser un tableau dynamique non membre de la classe.
  2. void Deck() n'est pas le constructeur de la classe Deck puisque vous avez manqué l'opérateur de résolution de la portée. Vous pouvez être confondu avec la définition du constructeur et de la fonction portant le nom Deck et le type renvoyé void.
  3. dans vos boucles, vous devez utiliser < pas > sinon la boucle ne sera jamais exécutée.
3
taocp

Spécifiez la carte de classe pour le constructeur:

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

Et définissez également le constructeur et le destructeur par défaut.

1
suspectus