Проблемы с классом отладки

Тема в разделе "Arduino & Shields", создана пользователем cfif, 8 май 2023.

  1. cfif

    cfif Нерд

    Камрады, столкнулся с такой проблемой. Делаю класс для отладки по сериал. Возникла путаница с #include. Помогите разобраться. Схема проекта следующая.
    Shop.h
    Код (C++):
    #ifndef SHOP_H
    #define SHOP_H

    #include <debugger.h>

    #include <product.h>

    class Shop
    {
    public:
    private:
      Product _prod;
    };

    #endif
    product.h
    Код (C++):
    #ifndef PRODUCT_H
    #define PRODUCT_H

    #include <debugger.h>

    class Product
    {
    public:
      int type = 1;

    private:
    };

    #endif
    product.cpp
    Код (C++):
    #include <product.h>
    debugger.h
    Код (C++):
    #ifndef DEBUGGER_H
    #define DEBUGGER_H

    #include <shop.h>

    class Debugger
    {
    public:
      bool var = false;

    private:
    };

    #endif
     

    При компиляции выдает ошибку: error: 'Product' does not name a type
    Если я в файле product.h убираю #include <debugger.h>, то всё гуд.
    И так вертел, и эдак - не пойму почему так((
     
  2. cfif

    cfif Нерд

    класс debugger будет синглтоном. Мне нужно, чтобы я из любого места программы мог его вызвать. Всё работало, пока не решил сделать еще красивше и не включить некоторые классы в сам класс debugger. На примере выше - это класс Shop. И тут пошло, поехало. Из кода убрал всё лишнее. Осталась только та часть, которая вызывает ошибку
     
  3. User248

    User248 Гик

    А зачем это раскидывать по разным файлам?
     
  4. cfif

    cfif Нерд

    у меня классы большие получаются. В одном файле неудобно
     
  5. cfif

    cfif Нерд

    да, кстати, если из файла product.cpp убрать #include <product.h>, тоже всё гуд. Такое ощущение, что я не до конца правильно понял концепцию include и где-то жестко туплю((
     
  6. User248

    User248 Гик

    #include <shop.h> в файле debugger.h кажется неуместным.
     
  7. cfif

    cfif Нерд

    в том то и дело - он мне там нужен. Я хочу создать объект класса shop в дебаггере и использовать данные этого объекта. Причем мне нужно и создать объект класса product в дебаггере и его тоже использовать
     
  8. User248

    User248 Гик

    Значит, #include <debugger.h> неуместен в файлах Shop.h и product.h
     
  9. cfif

    cfif Нерд

    Идея такая: в debugger.h создаю указатели на объекты классов shop и product. В файле main.cpp, при создании объектов классов shop и product, я передаю указатели на эти объекты в debugger.h. В debugger.h создаю функцию, например printShopData(). В main.cpp вызываю printShopData(). И спокойно в debugger.h внутри printShopData() вывожу нужные мне данные, чтобы код файла main.cpp был менее загружен и более читабелен.
     
  10. cfif

    cfif Нерд

    Если я уберу #include <debugger.h> из shop.h, то не смогу вызвать методы дебаггера из этого файла - он их не увидит
     
  11. User248

    User248 Гик

    А в чём это всё собирается? Файлы product.h и product.cpp должны быть включены в проект, иначе они не будут связаны между собой.
     
  12. cfif

    cfif Нерд

    собираю в Visual Studio Code. файлы включены в проект
     
  13. User248

    User248 Гик

    Без полного кода ничего не понятно.
     
  14. cfif

    cfif Нерд

    у меня все работало. В отладчике я выводил уже готовые данные, которые ему передавались из других файлов. Но проект разросся и теперь я хочу подготавливать данные уже внутри дебаггера (там и прием команд по Serial, и назначение переменных данными принятыми из Serial, и просто вывод данных)
     
  15. cfif

    cfif Нерд

    сейчас пример подготовлю
     
  16. cfif

    cfif Нерд

    main.cpp
    Код (C++):
    #include "debugger.h"

    #include <shop.h>

    Shop _shop;

    void setup()
    {
      Debugger::getDebugger()._shop = &_shop;
      Debugger::getDebugger()._product = &_shop._prod;
    }

    void loop()
    {
      // хочу проверить отладчиком данные
      Debugger::getDebugger().printShopData();
    }
     
    shop.h
    Код (C++):
    #ifndef SHOP_H
    #define SHOP_H

    // включил т.к. мне понадобится и здесь использовать отладчик
    // также как в product.h. Не стал расписывать , чтобы не загромождать код
    // принцип такой же как и в product.h и product.cpp
    #include <debugger.h>

    #include <product.h>

    class Shop
    {
    public:
      Product _prod;

    private:
    };

    #endif
    product.h
    Код (C++):
    #ifndef PRODUCT_H
    #define PRODUCT_H

    #include <debugger.h>

    class Product
    {
    public:
      void calculate();

    private:
    };

    #endif
    product.cpp
    Код (C++):
    #include <product.h>

    void Product::calculate()
    {
      // какие то вычисления
      // хочу их проверить отладчиком
      Debugger::getDebugger().printProductData();
    }
    debugger.h
    Код (C++):
    #ifndef DEBUGGER_H
    #define DEBUGGER_H

    #include <shop.h>
    #include <product.h>

    class Debugger
    {
    public:
      Shop *_shop;
      Product *_product;

      void printShopData();
      void printProductData();

      //*************************************************************
      // подготовка класса как singletone
      Debugger(const Debugger &) = delete;       // нужно чтобы объект класса был точно единственным
      void operator=(const Debugger &) = delete; // нужно чтобы объект класса был точно единственным

      static Debugger &getDebugger()
      {
        static Debugger dbg;

        return dbg;
      }
      //*************************************************************

    private:
      // Конструктор должен быть private для singletone
      Debugger() {}
    };

    #endif
     
     
  17. cfif

    cfif Нерд

    дебаггер я делаю синглтоном, чтобы иметь возможность из любого места программы обратиться к нему
     
  18. User248

    User248 Гик

    Это связано с защитой от редекларации #ifndef PRODUCT_H. Класс Product задекларировался и больше не виден компилятору. Меняйте структуру файлов на что-то более логичное.
     
    cfif нравится это.
  19. cfif

    cfif Нерд

    понял. Спасибо))
     
  20. User248

    User248 Гик

    В такой последовательности объявления объектов, код не будет собираться, даже если поместить всё в один файл. Вначале попробуйте запустить всё в одном файле, а потом уже пробуйте разделять.
     
    cfif и parovoZZ нравится это.