Подтвердить что ты не робот

С++ error 'Undefined ссылка на Class:: Function()'

Мне было интересно, может ли кто-нибудь помочь мне с этим - я только новичок в С++, и это вызывает у меня массу проблем.

Я пытаюсь сделать относительно простые объекты класса Deck и Card.

Ошибка появляется в "Deck.cpp", объявлении массива карт, а затем, когда я пытаюсь заполнить массив объектами карты. Там говорится undefined ссылка на 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;
}
4b9b3361

Ответ 1

Что вы используете для компиляции? Если существует ошибка ссылки undefined, обычно это потому, что файл .o(который создается из файла .cpp) не существует, и ваша система компилятора/сборки не может связать его.

Кроме того, в вашей card.cpp функция должна быть Card::Card() вместо void Card. Card:: - область охвата; это означает, что ваша функция Card() является членом класса 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. Включения чувствительны к регистру.

Ответ 2

В определении вашего класса Card появляется объявление для построения по умолчанию:

class Card
{
    // ...

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

    // ...
};

Но соответствующее определение не дается. Фактически это определение функции (из card.cpp):

void Card() {
//nothing
}

Определяет конструктор не, а скорее глобальную функцию с именем Card, которая возвращает void. Вы, вероятно, хотели написать это вместо:

Card::Card() {
//nothing
}

Если вы этого не сделаете, поскольку конструктор по умолчанию объявлен, но не определен, компоновщик выдает ошибку о ссылках undefined при обнаружении вызова конструктора по умолчанию.


То же самое относится к вашему конструктору, принимающему два аргумента. Это:

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() { }

Ответ 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++;
         }
    }
 }
  • cardArray - динамический массив, но не член класса Card. Странно, если вы хотите инициализировать динамический массив, который не является членом класса
  • void Deck() не является конструктором класса Deck, так как вы пропустили оператор разрешения области. Вас может смутить определение конструктора и функции с именем Deck и возвращаемым типом void.
  • в ваших циклах, вы должны использовать < not > иначе, цикл никогда не будет выполняться.

Ответ 4

Укажите карту класса для конструктора -:

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

И также определите конструктор по умолчанию и деструктор.