91 votes

Erreur C++ "Référence indéfinie à Class::Function()".

Je me demandais si quelqu'un pouvait m'aider à résoudre ce problème. Je suis novice en matière de C++ et cela me pose 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", lors de la déclaration d'un tableau de cartes, puis lorsque j'essaie de remplir le tableau avec des objets cartes. Il est dit qu'il y a une référence indéfinie à Card::Card() , Card::Card(Card::Rank, Card::Suit) y Card::~Card() .

J'ai toutes mes composantes apparemment correctes, donc je ne sais pas ce qui ne va pas.

Le code est le suivant :

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

86voto

maditya Points 3372

Qu'est-ce que tu utilises pour compiler ça ? S'il y a une erreur de référence non définie, c'est généralement parce que le fichier .o (qui est créé à partir du fichier .cpp) n'existe pas et que votre compilateur/système de construction n'est pas capable de le lier.

De plus, dans votre card.cpp, la fonction devrait être Card::Card() au lieu de void Card . Le site Card:: es scoping cela signifie que votre Card() est un membre de la classe Card (ce qui est évidemment le cas, puisque c'est le constructeur de cette classe). Sans cela, void Card est juste une fonction libre. De même,

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

devrait être

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

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

14voto

Andy Prowl Points 62121

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

class Card
{
    // ...

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

    // ...
};

Mais pas de correspondance définition est donné. En fait, cette définition de fonction (de card.cpp ) :

void Card() {
//nothing
}

Fait no définir un constructeur, mais plutôt une fonction globale appelée Card qui renvoie void . Vous vouliez probablement écrire ceci à la place :

Card::Card() {
//nothing
}

Si vous ne le faites pas, puisque le constructeur par défaut est déclaré mais non défini, l'éditeur de liens produira une erreur concernant les références non définies lorsqu'un appel au constructeur par défaut sera trouvé.


Il en va de même pour votre constructeur acceptant deux arguments. Ceci :

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

Il devrait être réécrit en 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é l'élément Card:: devant les noms des fonctions membres dans leurs définitions. Sans ce qualificatif, ces fonctions sont des fonctions globales plutôt que des définitions de fonctions membres.


Votre destructeur, quant à lui, est déclaré mais jamais défini. Fournissez simplement une définition pour lui dans card.cpp :

Card::~Card() { }

4voto

taocp Points 14822

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 pas un membre de Card la classe. Il est étrange que vous souhaitiez initialiser un tableau dynamique qui n'est pas membre de la classe
  2. void Deck() n'est pas un constructeur de la classe Deck puisque vous avez manqué l'élément opérateur de résolution de portée. Vous pouvez être confus en définissant le constructeur et la fonction avec le nom Deck et le type de retour void .
  3. dans vos boucles, vous devez utiliser < no > sinon, la boucle ne sera jamais jamais exécutée.

1voto

suspectus Points 5877

Spécifier 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.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X