главная гребаная проблема в больших проектах

Есть такие ошибки при сборке в С++, на которые сто раз наступаешь и каждый раз как заново.

#include

Проблема правильного включения заголовочных файлов (#include) при наследовании классов.

base class undefined

Вроде бы какая разница какие файлы h и где включаются, главное чтобы компилятор находил их в файловой системе. И как мы знаем включаются они один раз, так как все они стандартно должны защищаться синтаксисом #ifndef / #define / #endif.

Но есть наследование классов и тут надо дополнительно соблюдать еще одно правило - нельзя в родителе (в заголовочном файле класс родителя включать заголовочный файл потомка).

Все это трудно контролировать, так как один h файл может подключать внутри себя хренову тучу разных файлов h из разных мест.

Но первое, что надо исключить - это в самом первом файле наследований (в первом классе иерархии) все инклуды должны быть по минимуму.

И далее по цепочке наследований также делаем #include только базовых абстракций (их много). То есть не надо обобщать и пытаться всем инклудить один  файл, в котором якобы есть все инклуды всех файлов.

Ну вот к примеру первый файл в цепочке наследований (класс FnDoc):

#ifndef FNDOC_H
#define FNDOC_H

#include <QString>

class FnDoc
{

public:

    FnDoc();

    int fnDocNum;

    int unixDateTime;

    QString fnDocSign;

    bool isValid();
};


#endif // FNDOC_123_H

Тут инклудим только #include <QString>, потому что такой класс используется (в качестве переменной), то есть без него никак. И больше ничего не инклудим - это важно.

Второй файл в цепочке наследований например класс FnDocInfo:

#ifndef FNDOCINFO_H
#define FNDOCINFO_H

#include "abstract_kkt/fndoc.h"

class FnDocInfo : public FnDoc
{
public:
    FnDocInfo();

    bool ofd_received;
    uint type;
    uint size;
};

#endif // FNDOCINFO_H

Тут по минимуму инклудим только fndoc.h и больше ничего, так как больше ничего и не надо по сути.

Выводы

Все это относится к правильной иерархии классов, к правильному пониманию зависимости сущностей. Главное из которых в том, что класс родителя ничего недолжен знать о классе потомка.

 Поэтому когда вы переделываете иерархию классов не забывайте проверять и исправлять инклуды.

К правильным интклюдам можно отнести еще одну проблему.