Как правило, в файлы .h вы не хотите включать другие файлы заголовков. Это просто объявления, поэтому им не нужно знать, как выглядят другие классы. Удалите #include "blah.h"
и вместо этого напишите предварительные объявления class blah;
там, где они вам нужны. Это случай, ЕСЛИ вы храните объект blah
непосредственно в своем классе, и в этом случае вам нужно включить blah.h
, потому что компилятору необходимо знать, насколько велик этот объект. Вы можете избежать этих включений, если вместо этого вы храните указатель на объект вместо объекта напрямую (и это действительно более распространенная практика, поскольку вам не нужно копировать все данные при копировании конструкции).
РЕДАКТИРОВАТЬ: В качестве примечания вы обычно хотите включать только необходимые #includes
(а именно iostream), а также не использовать using namespace std;
в своих заголовках, потому что другой файл, включая ваш заголовок, может не захотеть использовать пространство имен std. Вместо этого сделайте это в файле реализации. Я внес соответствующие изменения ниже.
РЕДАКТИРОВАТЬ 2: Кроме того, имейте в виду, что map
- это тип структуры данных в std, поэтому будьте осторожны, когда вы называете вещи map
(я бы посоветовал использовать другое имя).
РЕДАКТИРОВАТЬ 3: Как указано в комментариях, стандартные контейнеры требуют полного объявления содержащихся в них объектов, поэтому всякий раз, когда у вас есть vector<blah>
, вы должны включать blah.h
. Также учтите следующее: проблематично включить объект blah
в его собственное объявление. Поскольку объект содержит экземпляр самого себя, это рекурсивно, так сколько места нужно выделить? Вы можете исправить это, указав pointer-to-blah
в blah
(указатель - это просто фиксированный размер int). По той же причине для класса Country
проблематично содержать класс vector<Country>
. ЭТО можно решить, заменив vector<Country>
на vector<Country*>
. Поэтому, чтобы сделать их технически компилируемыми по стандарту C++ и очистить дизайн в отношении включения других заголовков, я изменил переменные-члены, ссылающиеся на Country
, Continent
и Map
, на их соответствующие указатели, изменение, которое вам нужно отразить. в файлах реализации. Также я изменил Map(std::ifstream);
на Map(std::ifstream &);
, как было предложено в другом комментарии, так как я серьезно сомневаюсь, что вы намеревались скопировать сюда ifstream.
Код:
Карта.ч:
#ifndef MAP_H
#define MAP_H
#include<string>
#include<vector>
#include<fstream>
class Country;
class Continent;
class Map{
private:
std::vector<Country*> countries; // consider pointers instead
std::vector<Continent*> continents; // consider pointers instead
std::vector<std::vector<int> > adjacents; // (just ints, so no pointers needed)
std::string author;
std::string image;
std::string wrap;
std::string scroll;
std::string warn;
public:
Map(std::ifstream &);
Map();
void save();
void setAdjacent(Country&, Country&);
void placeWithin(Continent&, Country&);
int numOfCountries();
int numOfContinents();
bool verify();
bool isAdjacent(Country*, Country&);
bool hasAdjacent(Country*);
bool hasCountry(Continent&);
};
#endif
Континент.h:
#ifndef CONTINENT_H
#define CONTINENT_H
#include<string>
#include<vector>
class Country;
class Continent
{
private:
std::string name;
int bonus;
std::vector<Country*> countries;
public:
void addCountry(Country&);
int getOwner();
int getBonus();
int getSize();
std::string getName();
bool hasCountry(Country&);
};
#endif
Страна.ч:
#ifndef COUNTRY_H
#define COUNTRY_H
#include<string>
#include<vector>
class Map;
class Continent;
class Country{
private:
static int nextCountryNumber;
int countryNumber;
Map *map;
std::string name;
int x, y;
Continent *continent;
std::vector<Country*> adjacents;
public:
Country(std::string, int, int, Continent&, Map&);
std::string getName();
int getX();
int getY();
Continent getContinent();
bool isAdjacentTo(Country&);
bool hasAdjacent();
void addAdjacent(Country&);
std::string toString();
};
#endif
person
personjerry
schedule
05.11.2015
Map
используется вCountry
, аCountry.h
включаетContinent.h
, который включаетMap.h
- person GreatAndPowerfulOz   schedule 05.11.2015include
в заголовках. В противном случае вы можете столкнуться с циклическими зависимостями. И что конкретно за ошибка? Не могли бы вы вставить это здесь? - person personjerry   schedule 05.11.2015Map(std::ifstream);
может доставить вам неприятности. Передача потоков по значению не разрешалась до C++11, и некоторые основные компиляторы медленно реализовывали эту функцию.Map(std::ifstream &)
было бы более обычным. - person M.M   schedule 05.11.2015