Как разбить код C ++ на тело и заголовочный файл (ищем более конкретный пример)

Поиск ответов на этот вопрос дал несколько ответов, которые не имели большого смысла для меня как начинающего программиста на C.

Я программирую Arduinos, большинство из которых подключено к сети, и большинство из них включает датчик температуры для получения MAC-адреса. Все они публикуют сообщения через MQTT.

Мой файл .cpp выглядит так:

/*
Some description
*/

/* --------------- Configuration file --------------------------------------- */
#ifndef CONFIG_H
#   include "config.h"
#endif

/* --------------- Libraries ------------------------------------------------ */
#include <Arduino.h>                            // basic Arduino definitions
#include <avr/wdt.h>                            // watch dog
#include <stdbool.h>                            // boolean definition
#include <SPI.h>                                // Serial Peripheral Interface Bus
#include <Ethernet.h>                           // Ethernet library for EtherShield
#include <PubSubClient.h>                       // MQTT client library
#include <OneWire.h>                            // OneWire library for Dallas DSB etc.

// ----- global variables
...

/* --------------- Instantiate global objects ------------------------------- */
EthernetClient ethernet_client;                 // Ethernet
PubSubClient mqtt_client (ethernet_client);     // instantiate MQTT with ethernet_client


/* --------------- Prototypes ----------------------------------------------- */
// common static code modules
void mac_address_build (uint8_t pin);
void ethernet_connection_maintain ();
void bicolour_led_set (uint8_t ledState);
char *deblank (char *str);

void mac_address_publish ();
void message_publish (const char *topic, const char *msg);
void error_publish (uint8_t error_type, char *error_msg);

void temperature_collect ();
float temperature_get (uint8_t pin);
float temperature_validate (uint8_t pin, float temp_sensed);
void temperature_publish (float temp);

// common code but modify as required
bool b_connected_to_broker ();
void mqtt_call_back (char *topic, byte *payload, uint16_t length);

// controller specific functions
void meter_pulse_counter_isr();
void meter_values_calculate();
void meter_values_publish (float litres_total);
void soil_permittivity_measure();

/* --------------- Function declarations ------------------------------------ */
// as prototype above

void setup ()
{
}

void loop ()
{
}

Я подумал, что просто поместите стандартные модули статического кода и поместите их в standard_functions.cpp и включите его после config.h, например:

/* --------------- Standard functions --------------------------------------- */
#ifndef STD_FUNCTIONS
#define STD_FUNCTIONS
#   include "standard_functions.cpp"
#endif

Однако затем я получаю сообщения об ошибках, что идентификаторы не объявлены.

Я хотел бы иметь эти общие модули в отдельном файле, который я включаю в main.cpp, чтобы я мог поддерживать один включаемый файл для всех других программ, которые я мог бы написать.

Я прочитал: Следует ли мне использовать #include в заголовках? Как разделить это на заголовочный и исходный файлы? Как разделить код на несколько файлов

... что я не мог применить к моей «проблеме». Один даже предлагает мне создать еще один файл .h (в дополнение к .cpp).

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

Возможно ли, что это обычная практика, чтобы мои «стандартные_функции» содержались в одном файле (.cpp или .h), или мне нужны стандартные_functions.h и .cpp? Что есть в каждом? Когда я создаю standard_function.cpp и помещаю в него функции, я получаю около 70 сообщений с неопределенным идентификатором. Однако, когда я переименовываю standard_functions.cpp в .h, я получаю только одно сообщение об ошибке, которое, кажется, указывает на то, что это лучшее имя. Ошибка - переменная или поле mac_address_build объявлено недействительным; хотя код компилируется без ошибок, если все находится в одном файле. Однако при перемещении этой функции на второе место появляется больше ошибок о неопознанных идентификаторах.

Я разбивал файлы разными способами, и сообщения об ошибках продолжали накапливаться. Так что да, я не «понял».


person MaxG    schedule 25.09.2020    source источник
comment
Кажется, вы спрашиваете о C ++, который отличается от C. Я предлагаю настроить заголовок и теги.   -  person resiliware    schedule 25.09.2020
comment
У вас могут быть циклические зависимости, требующие предварительного объявления. Это довольно распространенное явление. Не включайте .cpp файлы. Предполагается, что источник CPP будет скомпилирован в объектный файл, а заголовки должны предоставить типы и интерфейсы, необходимые для ссылки на материал в этом объектном файле. Позже компоновщик объединяет все ваши объектные файлы вместе. Короче говоря, заголовок должен предоставлять объявления функций и типов, а исходный файл должен предоставлять фактическую реализацию.   -  person paddy    schedule 25.09.2020
comment
Ваша охрана включения задом наперед. Они принадлежат включенному файлу, а не директиве #include. Также рассмотрите #pragma once как альтернативу.   -  person bitmask    schedule 25.09.2020
comment
Что ж, я ценю всю мудрость, но, возможно, я слишком толст, чтобы понять это ... круговая зависимость, прямое объявление ... что касается объявлений типов, я должен определять uint_t и все такое? Я бы не нашел это полезным для упрощения вещей ?! Я считаю, что охранники - это #ifdef; так что если в этом случае они войдут в файл, чтобы быть включенными ?!   -  person MaxG    schedule 25.09.2020
comment
циклическая зависимость и форвардное объявление даже упоминается в Википедии. Это основные проблемы C ++ (и C). Так что, погуглив, вы можете найти учебные пособия и другие материалы, где это объясняется. - В общем: C ++ не является чем-то интуитивным, и его можно изучить, немного щелкнув (или проведя пальцем по экрану). Боюсь, вам нужно прочитать книгу (или статьи в Интернете), чтобы научиться делать что-то правильно (или принять то, что в ваших программах происходят странные вещи, а вы не знаете почему).   -  person Scheff's Cat    schedule 25.09.2020
comment
Я забыл защиту заголовков ... ;-)   -  person Scheff's Cat    schedule 25.09.2020
comment
Я понял это, посмотрев несколько Youtubes; Благодарю.   -  person MaxG    schedule 25.09.2020