Внешняя связь в С++

Я делаю простую программу, работающую с покерными руками и вероятностями. Я запускаю тестовые случаи на разных руках, и в моей программе мне нужна колода, из которой можно нарисовать свою руку, постоянную и глобальную. В моей программе есть три основных объекта: карта, рука и колода. Я пытаюсь создать глобальную колоду, но кажется, что бы я ни делал, я получаю сообщение об ошибке, говорящее, что globalDeck не определен в hand.cpp. Вот соответствующий код:

рука.cpp:

Hand::Hand(int &one, int &two, int &three, int &four, int &five)
{
    cardsinHand.push_back(globalDeck.copy(one));
    cardsinHand.push_back(globalDeck.copy(two));
    cardsinHand.push_back(globalDeck.copy(three));
    cardsinHand.push_back(globalDeck.copy(four));
    cardsinHand.push_back(globalDeck.copy(five));
}

и мой файл cardgames.cpp:

#include "stdafx.h"
#include<iostream>
#include "hand.h"
using namespace std;

Deck globalDeck;

void printresults(long successes, long trials)
......

Примечание. Я попытался заменить Deck globalDeck на extern Deck globalDeck, extern const globalDeck и т. д. и т. д. Кажется, ничто не делает так, чтобы globalDeck был определен в hand.cpp. Кроме того, колода будет оставаться неизменной на протяжении всей программы, поэтому ее можно объявить как глобальную константу или глобальную переменную, в зависимости от того, что проще. Мой вывод ошибки:

1>c:\users\\desktop\semesters past\winter 2013\computer programming\projects\cardgames\cardgames\hand.cpp(31): error C2065: 'globalDeck' : undeclared identifier
1>c:\users\\desktop\semesters past\winter 2013\computer programming\projects\cardgames\cardgames\hand.cpp(31): error C2228: left of '.copy' must have class/struct/union
1>          type is 'unknown-type'

person jntrcs    schedule 22.08.2015    source источник
comment
Вместо использования глобальной переменной используйте класс, который содержит ваше игровое состояние и обрабатывает действия игры в своих методах.   -  person Neil Kirk    schedule 23.08.2015


Ответы (3)


Объявите свою глобальную переменную в одном заголовочном файле

extern Deck globalDeck;

и определить его в cardgames.cpp

Deck globalDeck;

Объяснение: Компилятор должен увидеть, что такое globalDeck, прежде чем вы сможете его использовать. И компилятор чаще всего обрабатывает каждый *.cpp по отдельности, не глядя на другие. В заголовочных файлах вы можете сказать, что есть в программе, не давая полного и однозначного определения.

person aschepler    schedule 22.08.2015
comment
Добавил extern Deck globalDeck в stdafx.h и все заработало! Бонусные баллы, если вы можете объяснить мне, почему это необходимо, и что такое файлы заголовков и stdafx (я новичок). - person jntrcs; 23.08.2015
comment
Компилятор должен увидеть, что такое globalDeck, прежде чем вы сможете его использовать. И компилятор чаще всего обрабатывает каждый *.cpp по отдельности, не глядя на другие. В заголовочных файлах вы можете сказать, что есть в программе, не давая полного и однозначного определения. - person aschepler; 23.08.2015
comment
@aschepler объяснение должно быть добавлено непосредственно к вашему ответу. Все равно проголосовать - person LBes; 23.08.2015

Глобальная переменная globalDeck должна быть объявлена в каждой единице компиляции (файле .cpp), которая ее использует. Он должен быть определен ровно в одной единице компиляции.

Декларация формы

Deck globalDeck;

одновременно является объявлением и определением. Объявление с extern вроде:

extern Deck globalDeck;

является просто объявлением, а не определением.

Файлы заголовков (файлы .h) — это просто текст, который включается в другие файлы с #include. Таким образом, вы можете поместить объявление extern Decl globalDeck; в файл заголовка (любой файл заголовка) и #include этот файл заголовка в каждый файл .cpp. Вам также понадобится определение ровно в одном файле .cpp.

person Chris Dodd    schedule 23.08.2015

class Deck не был определен в hand.cpp из-за отсутствия заголовка. Вам нужно добавить что-то вроде #include "hand.h" или #include "deck.h".

person Potatoswatter    schedule 23.08.2015
comment
Необходимые включения есть; это всего лишь часть кода, а не весь файл. - person jntrcs; 23.08.2015