С++ 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;
}
Ответы
Ответ 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) {
И также определите конструктор по умолчанию и деструктор.