Как решить ошибку" не называет тип"


Я получаю следующую ошибку: 'class name' does not name a type для всех моих классов. Я подозреваю, что это может быть циклическая зависимость, но я понятия не имею, как ее решить, поскольку каждый класс требует доступа к функции из следующего. Ниже приведены мои классы:

Контейнер.h:

#ifndef CONTAINER_H
#define CONTAINER_H

#include "Factory.h"

class Container
{
public:
    Container()
    {
        array = new int[10];
        for (int i = 0; i < 10; ++i) {
            array[i] = i;
        }
    }
    Iterator* createIterator()
    {
        Factory fac;
        return fac.factoryMethod();
    }
    friend class Iterator;

private:
    int* array;
};

#endif //CONTAINER_H
Фабрика

.h:

#ifndef FACTORY_H
#define FACTORY_H

#include "Iterator.h";

class Factory
{
    Iterator* factoryMethod(Container* con)
    {
        return new Iterator(con);
    }
};

#endif //FACTORY_H

Итератор.h:

#ifndef ITERATOR_H
#define ITERATOR_H

#include "Container.h"

class Iterator
{
public:
    Iterator(Container* con)
    {
        this->con =con;
    }
    int getFromIndex(int i)
    {
        return con->array[i];
    }
private:
    Container* con;
};

#endif //ITERATOR_H

Главная.cpp:

#include <iostream>
using namespace std;

#include "Container.h"
#include "Iterator.h"

int main() {
    Container con;
    Iterator* it = con.createIterator();
    cout<<it->getFromIndex(2)<<endl;

    return 0;
}
Заранее благодарю вас за любую помощь.
2 3

2 ответа:

Это действительно циклическая зависимость между вашими заголовками. Container.h включает в себя Factory.h, который включает в себя Iterator.h, который включает в себя Container.h.

Решение заключается в перемещении реализаций функций-членов из заголовочных файлов в исходные файлы. Таким образом, заголовочные файлы будут нуждаться только в объявлениях, а не в определениях классов, которые вы можете легко поместить непосредственно в" потребляющие " заголовочные файлы:

class Iterator;

class Container
{
public:
    Container();
    Iterator* createIterator();
    friend class Iterator;

private:
    int* array;
};

Затем в соответствующем исходном файле (например, Container.cpp) реализуйте функции-члены и включите любые заголовки, которые вам нужны:

Контейнер.cpp

#include "Container.h"
#include "Factory.h"

Container::Container() : array(new int[10])
{
    for (int i = 0; i < 10; ++i) {
        array[i] = i;
    }
}

Iterator* Container::createIterator()
{
    Factory fac;
    return fac.factoryMethod();
}

(Dtto для Factory и Iterator, конечно).

Не забудьте связать все исходные файлы вместе при создании вашего окончательного двоичного файла.

Как сказал Дэн, поместите функциональные тела .cpp файлы (различные единицы перевода).

Кроме того, если вы используете только указатели на тип, вам не нужно #include его использовать. Просто сделайте форвард-объявление.