2015-04-13 2 views
1

У меня есть 2 класса, написанных в двух разных файлах: router.h - router.cpp и topology.h - topology.cpp.Агрегация не работает при написании классов в разных файлах

Я покажу содержимое файлов .h, потому что .cpp содержат только реализации.

router.h:

#ifndef _ROUTER_H_ 
#define _ROUTER_H_ 
#include <map> 
#include "topology.h" 

using namespace std; 

class Router { 

public: 
    int id; 
    map<Router, int> linkers; 
    Topology topology; 

    Router(); 
    Router(int id); 
    void addLink(Router router, int cost); 
    void delLink(Router router); 

}; 

#endif 

topology.h:

#ifndef _TOPOLOGY_H_ 
#define _TOPOLOGY_H_ 
#include "router.h" 

class Topology { 
public: 
    map<Router, int> graph; 
    Topology(); 
    void addNode(Router router, int cost); 
    void delNode(Router router); 
}; 

#endif 

Мой вопрос, почему при компиляции у меня есть ошибка, которая вызвана непризнанных классов маршрутизатора и топологии, даже если Я включил заголовки, и я добавил ifndefs, чтобы не включать файлы более одного? Я тоже посмотрел в интернете, на стек и ничего не нашел об этой проблеме.

ответ

1

Проблема в этом коде заключается в том, что ваша топология (Topology.h) использует объекты маршрутизатора, переданные по значению: компилятор должен иметь полное определение маршрутизатора. Это нормально, поэтому вы включаете Router.h. Однако вашему маршрутизатору нужен полный объект топологии (а не указатель, а не ссылка) для работы.

Таким образом, у вас есть конфигурация, в которой A требует полностью объявленного B, и B требует полностью объявленного полностью объявленного. Это проблема, как указано в комментариях, «Круговых зависимостей».

Что вы должны сделать, так это избежать объекта топологии в маршрутизаторе (вам может понадобиться указатель, потому что полный объект означает копирование, а не общий экземпляр). Используйте форвардную декларацию топологии в Router.h (и #include "Topology" в Router.cpp) и объявите свой атрибут «топология» в качестве указателя/умного указателя/ссылки.

+0

Нет необходимости использовать замену члена «Топология». Круговую зависимость можно зафиксировать простым переадресацией 'Router' в' topology.h' вместо этого. – bames53

1

router.h включает в себя topology.h, который пропускает в том числе из-за router.h включают охрану и затем использует класс Router в своем определении, которое не определено. Стандартное решение - пересылать объявляемые типы (например, class Router;). К сожалению, std::map требует полных типов и использование его с неполными типами является неопределенным поведением. Чтобы карта совместима с неполными типами, вы можете использовать std::unique_ptr<map<Router, int>> (или какой-либо другой тип указателя) или boost::container::map<Router, int>>.

Смежные вопросы