Для профи, сборка разбитого проекта по header'ам
-
V2oD2o
- Встал на лапы
- Сообщения: 90
- Зарегистрирован: Чт дек 09, 2010 12:03:08
- Откуда: Зеленоград
- Контактная информация:
Для профи, сборка разбитого проекта по header'ам
Всем привет, проект вырос, стало затруднительно продолжать разработку
Вынес все классы в разные .h файлы с описанием в .cpp, внутри каждого класса используется множество структур, в т.ч. вложенные и с функциями - где используются данные и функции других классов, таких же по сложности
Особенность всех IDE, и условно стандартной обработки через make all - например в блокноте - подразумевает сборку всех .cpp файлов в .o - по условию %.cpp - отсюда проблема видимости разными классами - других классов, и упорядочить include - не представляется возможным, т.е.:
#include one
#include two
#include three
one не будет видеть two и three т.к. они вызываются позже, как не тусуй очередность - всегда будет задействован какой либо функционал еще не подключенного файла
Предварительное объявление не актуально, эту роль выполняет .h
Еще при сборке .cpp от .h - есть проблема видимости констант и инклюдов указанных в main.cpp
Если собирать только один файл main.cpp - все собирается прекрасно, но времени уходит на сборку - куча, .cpp => .o => .elf => .bin, можно конечно какой нибудь пакетный файл сделать, но не хотелось бы отходить от makefile
Кто то встречал решения по данной проблеме, или может кто то разрабатывает что то серьёзнее чем однофайловый проект и тоже сталкивался ?
Может какие то директивы есть для указания того что файл .cpp является дополнением для заголовочного .h и его не надо обрабатывать до обработки файлов без директив?
Убрать использование одного класса из другого и передавать ссылки\указатели - не вариант, это будет over 9000 указателей для обработки нужных данных
Вынес все классы в разные .h файлы с описанием в .cpp, внутри каждого класса используется множество структур, в т.ч. вложенные и с функциями - где используются данные и функции других классов, таких же по сложности
Особенность всех IDE, и условно стандартной обработки через make all - например в блокноте - подразумевает сборку всех .cpp файлов в .o - по условию %.cpp - отсюда проблема видимости разными классами - других классов, и упорядочить include - не представляется возможным, т.е.:
#include one
#include two
#include three
one не будет видеть two и three т.к. они вызываются позже, как не тусуй очередность - всегда будет задействован какой либо функционал еще не подключенного файла
Предварительное объявление не актуально, эту роль выполняет .h
Еще при сборке .cpp от .h - есть проблема видимости констант и инклюдов указанных в main.cpp
Если собирать только один файл main.cpp - все собирается прекрасно, но времени уходит на сборку - куча, .cpp => .o => .elf => .bin, можно конечно какой нибудь пакетный файл сделать, но не хотелось бы отходить от makefile
Кто то встречал решения по данной проблеме, или может кто то разрабатывает что то серьёзнее чем однофайловый проект и тоже сталкивался ?
Может какие то директивы есть для указания того что файл .cpp является дополнением для заголовочного .h и его не надо обрабатывать до обработки файлов без директив?
Убрать использование одного класса из другого и передавать ссылки\указатели - не вариант, это будет over 9000 указателей для обработки нужных данных
- Реклама
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Для профи, сборка разбитого проекта по header'ам
Какие-то надуманные проблемы. Посмотрите как сделаны те же stm-овские библиотеки - там десятки модулей. Если правильно заголовочные файлы оформлять, то никаких проблем не возникает. Можно подробнее обсудить разные подходы, если есть желание.
Re: Для профи, сборка разбитого проекта по header'ам
"Мешанинина" у Вас какая-то.
[uquote="V2oD2o",url="/forum/viewtopic.php?p=3421610#p3421610"]Особенность всех IDE, и условно стандартной обработки через make all - например в блокноте - подразумевает сборку всех .cpp файлов в .o - по условию %.cpp - отсюда проблема видимости разными классами - других классов, и упорядочить include - не представляется возможным, т.е.:[/uquote]
В си/С++ раздельная компиляция. Т.е. каждый файл *.c/*.cpp компилируется независимо от других. Из этого Вы и должны исходить.
Если не рассматривать, совсем редкие и экзотические случаи, то *.c/*.cpp вообще никогда никуда не инклудятся.
[uquote="V2oD2o",url="/forum/viewtopic.php?p=3421610#p3421610"]Может какие то директивы есть для указания того что файл .cpp является дополнением для заголовочного .h и его не надо обрабатывать до обработки файлов без директив?[/uquote]
Как *.cpp может являться дополнением *.h файла??? *.cpp - это исходники. В *.h файлах вообще не должно быть того, что генерирует код.
Я бы сказал, что *.h файл является дополнением c/cpp файла (если предположить, что слово "дополнение" здесь может быть применимо), так как в нем описан интерфейс использования объектов/функций из реализация которых находится в *.с/с++ файлах.
===
ЗЫ. привели бы маленький пример, в котором видны Ваши проблемы. Лично я не понял, что вызывает у Вас затруднения.
[uquote="V2oD2o",url="/forum/viewtopic.php?p=3421610#p3421610"]Особенность всех IDE, и условно стандартной обработки через make all - например в блокноте - подразумевает сборку всех .cpp файлов в .o - по условию %.cpp - отсюда проблема видимости разными классами - других классов, и упорядочить include - не представляется возможным, т.е.:[/uquote]
В си/С++ раздельная компиляция. Т.е. каждый файл *.c/*.cpp компилируется независимо от других. Из этого Вы и должны исходить.
Если не рассматривать, совсем редкие и экзотические случаи, то *.c/*.cpp вообще никогда никуда не инклудятся.
[uquote="V2oD2o",url="/forum/viewtopic.php?p=3421610#p3421610"]Может какие то директивы есть для указания того что файл .cpp является дополнением для заголовочного .h и его не надо обрабатывать до обработки файлов без директив?[/uquote]
Как *.cpp может являться дополнением *.h файла??? *.cpp - это исходники. В *.h файлах вообще не должно быть того, что генерирует код.
Я бы сказал, что *.h файл является дополнением c/cpp файла (если предположить, что слово "дополнение" здесь может быть применимо), так как в нем описан интерфейс использования объектов/функций из реализация которых находится в *.с/с++ файлах.
===
ЗЫ. привели бы маленький пример, в котором видны Ваши проблемы. Лично я не понял, что вызывает у Вас затруднения.
Последний раз редактировалось viiv Ср июл 18, 2018 17:30:58, всего редактировалось 2 раза.
Re: Для профи, сборка разбитого проекта по header'ам
[uquote="V2oD2o",url="/forum/viewtopic.php?p=3421610#p3421610"]Вынес все классы в разные .h файлы с описанием в .cpp[/uquote]
Это как? Тоже хотелось бы глянуть на пример...
Это как? Тоже хотелось бы глянуть на пример...
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Для профи, сборка разбитого проекта по header'ам
Что-то мне подсказывает, что ТС если про препроцессор если и слышал, то не видел 
- Реклама
Re: Для профи, сборка разбитого проекта по header'ам
V2oD2o, вы сперва с просто С разберитесь и основами компиляции, а уж потом на плюсы посматривайте.
И если это вАААще первое ваше знакомство с яву и МК , то плюсы вообще крайне противопоказаны ...
И если это вАААще первое ваше знакомство с яву и МК , то плюсы вообще крайне противопоказаны ...
Re: Для профи, сборка разбитого проекта по header'ам
[uquote="V2oD2o",url="/forum/viewtopic.php?p=3421610#p3421610"]Всем привет, проект вырос, стало затруднительно продолжать разработку
Вынес все классы в разные .h файлы с описанием в .cpp, внутри каждого класса используется множество структур, в т.ч. вложенные и с функциями - где используются данные и функции других классов, таких же по сложности[/uquote]
А зачем классы внутри класса если это только не наследование? Скорее всего в этом и проблема. Класс - это самодостаточный объект, и он не должен зависеть от наличия другого класса и редко, когда внутри класса используются внешние объявления переменных или констант.
Все что нужно, передается в класс либо частями, либо в виде структуры, так проще.
Если класс самодостаточный, то он будет использоваться в головном файле, вы же все равно создадите объект.
И юзайте их вдоль и поперек и инклуды вешайте как угодно.
Если надо класс сделать в классе, то подумайте, может проще сделать наследование и добавить нужные методы,
чем делать перекрестные ссылки.
Вынес все классы в разные .h файлы с описанием в .cpp, внутри каждого класса используется множество структур, в т.ч. вложенные и с функциями - где используются данные и функции других классов, таких же по сложности[/uquote]
А зачем классы внутри класса если это только не наследование? Скорее всего в этом и проблема. Класс - это самодостаточный объект, и он не должен зависеть от наличия другого класса и редко, когда внутри класса используются внешние объявления переменных или констант.
Все что нужно, передается в класс либо частями, либо в виде структуры, так проще.
Если все привести в порядок, то будет все видеться. Ведь инклуды от классов, это всего лишь предварительные объявления.Особенность всех IDE, и условно стандартной обработки через make all - например в блокноте - подразумевает сборку всех .cpp файлов в .o - по условию %.cpp - отсюда проблема видимости разными классами - других классов, и упорядочить include - не представляется возможным, т.е.:
#include one
#include two
#include three
one не будет видеть two и three т.к. они вызываются позже, как не тусуй очередность - всегда будет задействован какой либо функционал еще не подключенного файла
Если класс самодостаточный, то он будет использоваться в головном файле, вы же все равно создадите объект.
Код: Выделить всё
#include one
#include two
#include three
...
one *Class1;
two *Class2;
three *Class3 ;
.....
Class1->init();
Class1->Dofunc1(&struct1);
Class1->exit();
delete Class1;
....
....
Если надо класс сделать в классе, то подумайте, может проще сделать наследование и добавить нужные методы,
чем делать перекрестные ссылки.
-
V2oD2o
- Встал на лапы
- Сообщения: 90
- Зарегистрирован: Чт дек 09, 2010 12:03:08
- Откуда: Зеленоград
- Контактная информация:
Re: Для профи, сборка разбитого проекта по header'ам
[uquote="VladislavS",url="/forum/viewtopic.php?p=3421638#p3421638"]Какие-то надуманные проблемы. Посмотрите как сделаны те же stm-овские библиотеки - там десятки модулей. Если правильно заголовочные файлы оформлять, то никаких проблем не возникает. Можно подробнее обсудить разные подходы, если есть желание.[/uquote]
Вопрос не понят, да и библиотеки не используются
Добавлено after 1 minute 49 seconds:
[uquote="dosikus",url="/forum/viewtopic.php?p=3421667#p3421667"]V2oD2o, вы сперва с просто С разберитесь и основами компиляции, а уж потом на плюсы посматривайте.
И если это вАААще первое ваше знакомство с яву и МК , то плюсы вообще крайне противопоказаны ...[/uquote]
не по теме
Добавлено after 11 minutes 9 seconds:
Что то видимо без примера сложно понять..
Вопрос не понят, да и библиотеки не используются
Добавлено after 1 minute 49 seconds:
[uquote="dosikus",url="/forum/viewtopic.php?p=3421667#p3421667"]V2oD2o, вы сперва с просто С разберитесь и основами компиляции, а уж потом на плюсы посматривайте.
И если это вАААще первое ваше знакомство с яву и МК , то плюсы вообще крайне противопоказаны ...[/uquote]
не по теме
Добавлено after 11 minutes 9 seconds:
Что то видимо без примера сложно понять..
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Для профи, сборка разбитого проекта по header'ам
[uquote="V2oD2o",url="/forum/viewtopic.php?p=3421735#p3421735"]Вопрос не понят[/uquote]Давайте с чего-нибудь начнём. Вот пример небольшого класса. Что из этого непонятно?
hmc704t.h
hmc704t.cpp
main.h
main.cpp
[uquote="dosikus",url="/forum/viewtopic.php?p=3421667#p3421667"]V2oD2o, вы сперва с просто С разберитесь и основами компиляции, а уж потом на плюсы посматривайте.[/uquote]Вместе с тем, в плюсах есть такая штука как namespace, которая сильно помогает в этом деле.
[uquote="Zat",url="/forum/viewtopic.php?p=3421668#p3421668"]либо в виде структуры[/uquote]В плюсах класс и структура это одно и то же, за мелким отличием.
hmc704t.h
Спойлер
Код: Выделить всё
#ifndef HMC704T_H
#define HMC704T_H
namespace HMC704T_NAMESPACE
{
using namespace IOPORTS;
typedef PD_2 LE1;
typedef PC_15 LE2;
typedef PA_8 LE3;
typedef struct
{
uint8_t HiKcp;
uint8_t CP;
} HMC704_CP;
template <const uint8_t NUM, class LE_PIN>
class HMC704T
{
public:
HMC704T() { chan = 0; };
void SetHMCMode(void) { LE=1; __no_operation(); LE=0; };
void SetChannel(uint8_t);
auto GetChannel(void) { return chan; };
void FirstLoad(uint8_t);
private:
void SetFreq(uint16_t f);
void SetReg(uint8_t reg, uint32_t value);
uint8_t chan;
LE_PIN LE;
PC_10 SCK;
PC_12 DATA;
PC_13 SW3;
};
} //namespace HMC704T_NAMESPACE
namespace SNT=HMC704T_NAMESPACE;
#ifdef HMC704T_CPP
SNT::HMC704T<1,SNT::LE3> snt1; // Синтезатор ПРМ 10.0-13.0 ГГц (по схеме на LE3)
SNT::HMC704T<2,SNT::LE2> snt2; // Синтезатор ПРД 10.0 ГГц (по схеме на LE2)
SNT::HMC704T<3,SNT::LE1> snt3; // Синтезатор ПРД 10.0-11.5 ГГц (по схеме на LE1)
template class SNT::HMC704T<1,SNT::LE3>;
template class SNT::HMC704T<2,SNT::LE2>;
template class SNT::HMC704T<3,SNT::LE1>;
#else
extern SNT::HMC704T<1,SNT::LE3> snt1;
extern SNT::HMC704T<2,SNT::LE2> snt2;
extern SNT::HMC704T<3,SNT::LE1> snt3;
#endif //HMC704T_CPP
#endif //HMC704T_HСпойлер
Код: Выделить всё
#define HMC704T_CPP
#include "main.h"
namespace HMC704T_NAMESPACE
{
// Задать номер канала 0-60
template <const uint8_t NUM, class LE_PIN>
void HMC704T<NUM,LE_PIN>::SetChannel(uint8_t channel)
{
if(NUM==1) //У синтезатора ПРМ переключаемый ГУН
{
if(channel>28) SW3=1; else SW3=0;
}
if(channel>60) channel=60;
SetFreq(channel*50+10000);
chan=channel;
}
// Первая загрузка с частотой из EEPROM
template <const uint8_t NUM, class LE_PIN>
void HMC704T<NUM,LE_PIN>::FirstLoad(uint8_t ch)
{
SetReg(0x00,(1<<5)); //Генерировать RESET
SetReg(0x01,(1<<1)); //Chip Enable
SetReg(0x02,2); //R=2
//SetReg(0x06,0x030F4A); //Frac
SetReg(0x06,0x0307CA); //Int
SetReg(0x07,0x00014D);
SetReg(0x08,0x09BEFF); //Analog EN
SetReg(0x0B,0x078071);
SetReg(0x0F,0x000001);
SetChannel(ch);
chan=ch;
};
extern const HMC704_CP cpVSfreq[];
// Задать частоту c шагом 1 МГц
template <const uint8_t NUM, class LE_PIN>
void HMC704T<NUM,LE_PIN>::SetFreq(uint16_t f)
{
uint8_t LEAK_MAG = 80; // 0.4 мА
uint8_t chan = (f-10000)/50;
uint8_t HiKcp = cpVSfreq[chan].HiKcp;
uint8_t CP = cpVSfreq[chan].CP;
uint8_t intg = f/200;
uint32_t frac = (f%200)*4194304L/50;
if(frac==0)
{
SetReg(0x06,0x0307CA); //Int
}
else
{
SetReg(0x06,0x030F4E); //Frac
}
SetReg(0x03,intg);
SetReg(0x04,frac);
SetReg(0x09, ((uint32_t)HiKcp<<23) | (1L<<22) | ((uint32_t)LEAK_MAG<<14) | (CP<<7)| CP); //CP_DN
};
template <const uint8_t NUM, class LE_PIN>
void HMC704T<NUM,LE_PIN>::SetReg(uint8_t reg, uint32_t value)
{
uint32_t tmp = ((uint32_t)(reg&0x3F)<<25)|((value&0x00FFFFFF)<<1);
LE=1;
for(auto mask=0x80000000U;mask;)
{
SCK=0;
DATA = (tmp & mask) ? 1 : 0;
mask >>=1;
SCK=1;
}
__no_operation(); __no_operation(); __no_operation();
SCK=0;
LE=0;
};
const HMC704_CP cpVSfreq[61] = { // { HiKcp, CP }
{ 1, 0 }, { 1, 5 }, { 1, 10 }, { 1, 15 }, // 10'000 10'050 10'100 10'150
{ 1, 20 }, { 1, 25 }, { 1, 30 }, { 1, 35 }, // 10'200 10'250 10'300 10'350
{ 1, 40 }, { 1, 45 }, { 1, 50 }, { 1, 50 }, // 10'400 10'450 10'500 10'550
{ 1, 50 }, { 1, 50 }, { 1, 50 }, { 1, 50 }, // 10'600 10'650 10'700 10'750
{ 1, 50 }, { 1, 50 }, { 1, 50 }, { 1, 50 }, // 10'800 10'850 10'900 10'950
{ 1, 65 }, { 1, 65 }, { 1, 65 }, { 1, 65 }, // 11'000 11'050 11'100 11'150
{ 1, 65 }, { 1, 75 }, { 1, 75 }, { 1, 75 }, // 11'200 11'250 11'300 11'350
{ 1, 75 }, { 1, 0 }, { 1, 0 }, { 1, 0 }, // 11'400 11'450 11'500 11'550
{ 1, 5 }, { 1, 5 }, { 1, 5 }, { 1, 5 }, // 11'600 11'650 11'700 11'750
{ 1, 5 }, { 1, 10 }, { 1, 15 }, { 1, 20 }, // 11'800 11'850 11'900 11'950
{ 1, 25 }, { 1, 25 }, { 1, 30 }, { 1, 30 }, // 12'000 12'050 12'100 12'150
{ 1, 35 }, { 1, 35 }, { 1, 40 }, { 1, 40 }, // 12'200 12'250 12'300 12'350
{ 1, 45 }, { 1, 45 }, { 1, 50 }, { 1, 50 }, // 12'400 12'450 12'500 12'550
{ 1, 55 }, { 1, 55 }, { 1, 60 }, { 1, 65 }, // 12'600 12'650 12'700 12'750
{ 1, 65 }, { 1, 65 }, { 1, 65 }, { 1, 65 }, // 12'800 12'850 12'900 12'950
{ 1, 65 } }; // 13'000
// 5=0,1 мА 25=0,5 мА 50=1,0 мА 65=1,3 мА 75=1,5 мА
}Спойлер
Код: Выделить всё
#ifndef MAIN_H
#define MAIN_H
#include "stm32f107xc.h"
#include <intrinsics.h>
#include <stdint.h>
#include <locale.h>
#include <stdio.h>
#include <string.h>
#include "SEGGER_RTT_Conf.h"
#include "SEGGER_RTT.H"
#include "gpio_stm32f1.h"
#include "lcd.h"
#include "Keyboard.h"
#include "Eth_Adresses.h"
#include "Eth.h"
#include "hmc629.h"
#include "hmc704T.h"
#include "EEPROM.h"
#include "Delay.h"
#include "usb_interrupt.h"
#include "usb_device.h"
#include "usb_cdc.h"
#define HSE_VALUE 8'000'000UL
#define CPU_FREQ 72'000'000UL
#endif //MAIN_H
Спойлер
Код: Выделить всё
#include "main.h"
int main()
{
//Перевод hmc704 в режим HMC Mode
snt1.SetHMCMode();
snt2.SetHMCMode();
snt3.SetHMCMode();
snt1.FirstLoad(0);
snt2.FirstLoad(0);
snt3.FirstLoad(0);
for(;;)
{
if(usb.isCommandReceived()) tna.DoCommand();
};
}
[uquote="Zat",url="/forum/viewtopic.php?p=3421668#p3421668"]либо в виде структуры[/uquote]В плюсах класс и структура это одно и то же, за мелким отличием.
Re: Для профи, сборка разбитого проекта по header'ам
Кстати, а для чего вот это - #define HMC704T_CPP ?
И потом вот это #ifdef HMC704T_CPP ....
Зачем делать:
#define HMC704T_CPP
#include "main.h"
Объявления внешних констант можно было и в .h запихать (extern const HMC704_CP cpVSfreq[]
,
чего им делать в .cpp
И смысл использовать выбор шаблона класса в препроцессоре ?
Не проще бы просто вначале того же main.h при компиляции 2 строчки раскомментировать и все ?
Или проще вспоминать, где же там идет выбор шаблона...
Да и объявление класса можно было в main тогда вынести и было бы видно где он объявляется,
а не гадать. Проще даже отлаживать.
Структура и класс это почти одно и тоже, разве что некоторые формальности опущены. Но это тут ни причем.
Просто видать писалось все это давно, потом рихтовалось и пыталось взлететь.
Честно говоря, наверное надо просто составить структуру программы, классы сделать без вставок препроцессоров
и будет все проще и понятней. Честно говоря, тяжело будет кому-то потом это все понимать.
Классы мелкие, думаю можно их переправлять постепенно.
Но как говорится, работает... ничего не меняй.
И потом вот это #ifdef HMC704T_CPP ....
Зачем делать:
#define HMC704T_CPP
#include "main.h"
Объявления внешних констант можно было и в .h запихать (extern const HMC704_CP cpVSfreq[]
чего им делать в .cpp
И смысл использовать выбор шаблона класса в препроцессоре ?
Не проще бы просто вначале того же main.h при компиляции 2 строчки раскомментировать и все ?
Или проще вспоминать, где же там идет выбор шаблона...
Да и объявление класса можно было в main тогда вынести и было бы видно где он объявляется,
а не гадать. Проще даже отлаживать.
Структура и класс это почти одно и тоже, разве что некоторые формальности опущены. Но это тут ни причем.
Просто видать писалось все это давно, потом рихтовалось и пыталось взлететь.
Честно говоря, наверное надо просто составить структуру программы, классы сделать без вставок препроцессоров
и будет все проще и понятней. Честно говоря, тяжело будет кому-то потом это все понимать.
Классы мелкие, думаю можно их переправлять постепенно.
Но как говорится, работает... ничего не меняй.
- VladislavS
- Собутыльник Кота
- Сообщения: 2562
- Зарегистрирован: Вт май 01, 2018 19:44:47
Re: Для профи, сборка разбитого проекта по header'ам
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Кстати, а для чего вот это - #define HMC704T_CPP ?
И потом вот это #ifdef HMC704T_CPP ....
Зачем делать:
#define HMC704T_CPP
#include "main.h"[/uquote]Потому что, в заголовочном файле есть часть кода, которая предназначена только для "своего" модуля. Глобальные переменные и экземпляры самого класса, которые должны быть видны наружу, я объявляю в заголовочном файле, так как это часть интерфейса модуля. Надо продублировать объявление и extern на него. Я делаю это в одном месте - так проще писать и тяжелее ошибиться. Если делать это в разных местах, то труднее контролировать всё ли объявлено и одинаково ли объявлено. Конечно же, компилятор, ткнёт носом, но потом по разным файлам не надо лазить, чтобы привести всё в соответствие. Или, например, объявлены выходы процессора, к которым подключен синтезатор. Когда я буду использовать этот класс в другом проекте, то подключу заголовочный файл, поправлю только в нём определение выводов и всё. Всё что касается описания/параметризации интерфейса модуля сосредоточено в одном месте. А так как вне модуля никому не положено знать про ножки к которым подключен синтезатор, то они спрятаны под ифдеф и как бы сосланы в cpp. Тем более, что выводы это не просто какие-то дефайны, а серьёзные классы из другого пространства имён.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Объявления внешних констант можно было и в .h запихать (extern const HMC704_CP cpVSfreq[]
,
чего им делать в .cpp[/uquote]А что ей делать в .h? Она закрытая, используется только в одном методе класса, зачем её светить всему миру? В заголовочном файле только интерфейс модуля. Возможно, вас смутил extern, но в данном случае он не светит наружу массив, а лишь предварительно описывает его тип чтобы можно было использовать в методе класса. А само определение массива в конце модуля, чтобы не засорять реализации методов мусорными данными.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]И смысл использовать выбор шаблона класса в препроцессоре ?
Не проще бы просто вначале того же main.h при компиляции 2 строчки раскомментировать и все ?
Или проще вспоминать, где же там идет выбор шаблона...[/uquote]Шаблоны это вообще отдельная тема. Я специально пример с шаблоном взял, чтобы вопросы появились. С шаблонами всегда идёт борьба с компилятором, чтобы он инстанцировал все нужные реализации да ещё не там где он хочет, а там где хочу я, чтобы сохранить модульность программы. Творческий процесс всегда
В данном случае я создаю три объекта класса синтезатора и объявляю интерфейс к ним. Другие модули ничего о шаблонах знать не должны, они знают лишь что есть эти три объекта и как ими пользоваться.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Да и объявление класса можно было в main тогда вынести и было бы видно где он объявляется,
а не гадать. Проще даже отлаживать.[/uquote]Почему в main? Он и в других модулях используется. Нет уж, всё что касается объявлений класса должно быть сосредоточено в модуле в котором он живёт. Зачем мне по всему проекту это размазывать. Чтобы использовать классы/объёкты модуля, достаточно просто подключить его заголовочный файл. Всё что нужно для работы модуля, написано/скрыто внутри модуля.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Структура и класс это почти одно и тоже, разве что некоторые формальности опущены. Но это тут ни причем.[/uquote]Мимо
У структуры кишки по умолчанию public, а у класса private - вот и всё отличие.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Просто видать писалось все это давно, потом рихтовалось и пыталось взлететь.[/uquote]Нет, тут ничего не притянуто за уши, каждая строка это осознанный выбор на этапе написания модуля. Остальные модули построены по тому же принципу.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Честно говоря, наверное надо просто составить структуру программы, классы сделать без вставок препроцессоров и будет все проще и понятней. Честно говоря, тяжело будет кому-то потом это все понимать.[/uquote]Можете на моём примере показать как?
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Классы мелкие, думаю можно их переправлять постепенно.
Но как говорится, работает... ничего не меняй.[/uquote]Что вы там переправлять собрались? Всё написано и работает ровно так как задумано.
Спасибо за содержательные вопросы, думаю ТС будет над чем подумать.
И потом вот это #ifdef HMC704T_CPP ....
Зачем делать:
#define HMC704T_CPP
#include "main.h"[/uquote]Потому что, в заголовочном файле есть часть кода, которая предназначена только для "своего" модуля. Глобальные переменные и экземпляры самого класса, которые должны быть видны наружу, я объявляю в заголовочном файле, так как это часть интерфейса модуля. Надо продублировать объявление и extern на него. Я делаю это в одном месте - так проще писать и тяжелее ошибиться. Если делать это в разных местах, то труднее контролировать всё ли объявлено и одинаково ли объявлено. Конечно же, компилятор, ткнёт носом, но потом по разным файлам не надо лазить, чтобы привести всё в соответствие. Или, например, объявлены выходы процессора, к которым подключен синтезатор. Когда я буду использовать этот класс в другом проекте, то подключу заголовочный файл, поправлю только в нём определение выводов и всё. Всё что касается описания/параметризации интерфейса модуля сосредоточено в одном месте. А так как вне модуля никому не положено знать про ножки к которым подключен синтезатор, то они спрятаны под ифдеф и как бы сосланы в cpp. Тем более, что выводы это не просто какие-то дефайны, а серьёзные классы из другого пространства имён.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Объявления внешних констант можно было и в .h запихать (extern const HMC704_CP cpVSfreq[]
чего им делать в .cpp[/uquote]А что ей делать в .h? Она закрытая, используется только в одном методе класса, зачем её светить всему миру? В заголовочном файле только интерфейс модуля. Возможно, вас смутил extern, но в данном случае он не светит наружу массив, а лишь предварительно описывает его тип чтобы можно было использовать в методе класса. А само определение массива в конце модуля, чтобы не засорять реализации методов мусорными данными.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]И смысл использовать выбор шаблона класса в препроцессоре ?
Не проще бы просто вначале того же main.h при компиляции 2 строчки раскомментировать и все ?
Или проще вспоминать, где же там идет выбор шаблона...[/uquote]Шаблоны это вообще отдельная тема. Я специально пример с шаблоном взял, чтобы вопросы появились. С шаблонами всегда идёт борьба с компилятором, чтобы он инстанцировал все нужные реализации да ещё не там где он хочет, а там где хочу я, чтобы сохранить модульность программы. Творческий процесс всегда
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Да и объявление класса можно было в main тогда вынести и было бы видно где он объявляется,
а не гадать. Проще даже отлаживать.[/uquote]Почему в main? Он и в других модулях используется. Нет уж, всё что касается объявлений класса должно быть сосредоточено в модуле в котором он живёт. Зачем мне по всему проекту это размазывать. Чтобы использовать классы/объёкты модуля, достаточно просто подключить его заголовочный файл. Всё что нужно для работы модуля, написано/скрыто внутри модуля.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Структура и класс это почти одно и тоже, разве что некоторые формальности опущены. Но это тут ни причем.[/uquote]Мимо
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Просто видать писалось все это давно, потом рихтовалось и пыталось взлететь.[/uquote]Нет, тут ничего не притянуто за уши, каждая строка это осознанный выбор на этапе написания модуля. Остальные модули построены по тому же принципу.
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Честно говоря, наверное надо просто составить структуру программы, классы сделать без вставок препроцессоров и будет все проще и понятней. Честно говоря, тяжело будет кому-то потом это все понимать.[/uquote]Можете на моём примере показать как?
[uquote="Zat",url="/forum/viewtopic.php?p=3421841#p3421841"]Классы мелкие, думаю можно их переправлять постепенно.
Но как говорится, работает... ничего не меняй.[/uquote]Что вы там переправлять собрались? Всё написано и работает ровно так как задумано.
Спасибо за содержательные вопросы, думаю ТС будет над чем подумать.
Re: Для профи, сборка разбитого проекта по header'ам
[uquote="V2oD2o",url="/forum/viewtopic.php?p=3421610#p3421610"]one не будет видеть two и three т.к. они вызываются позже, как не тусуй очередность - всегда будет задействован какой либо функционал еще не подключенного файла[/uquote]
Мне конечно не сложно повторить, но, чего вы ожидали, если ваш класс объявляется сразу после описания его реализации?
Если вы его не объявите, то у вас будут ошибки в компиляции, т.к. другие классы ничего еще о нем не знают.
А если вы его просто не хотите использовать больше, то что еще отвалится?
Я в свое время от этого отказался, т.к. иногда лишние модули становятся не нужны, и я просто в main комментирую 1 строку
и нужные блоки (можно даже через ifndef это сделать, если проектов много, а функционал часто используется).
Чтобы из 10 модулей оставить только 2, я даже не думаю, что там у них внутри. Просто выключаю в головном файле лишнее
и компилю. Если через препроцессор, то закомментировать 8 дефайнов куда проще, чем искать, что там еще отвалится.
Как-то так.
Мне конечно не сложно повторить, но, чего вы ожидали, если ваш класс объявляется сразу после описания его реализации?
Если вы его не объявите, то у вас будут ошибки в компиляции, т.к. другие классы ничего еще о нем не знают.
А если вы его просто не хотите использовать больше, то что еще отвалится?
Я в свое время от этого отказался, т.к. иногда лишние модули становятся не нужны, и я просто в main комментирую 1 строку
и нужные блоки (можно даже через ifndef это сделать, если проектов много, а функционал часто используется).
Чтобы из 10 модулей оставить только 2, я даже не думаю, что там у них внутри. Просто выключаю в головном файле лишнее
и компилю. Если через препроцессор, то закомментировать 8 дефайнов куда проще, чем искать, что там еще отвалится.
Как-то так.
-
V2oD2o
- Встал на лапы
- Сообщения: 90
- Зарегистрирован: Чт дек 09, 2010 12:03:08
- Откуда: Зеленоград
- Контактная информация:
Re: Для профи, сборка разбитого проекта по header'ам
Надо будет реальный пример собрать, а то кто в лес кто по дрова, суть всего выше-написанного понятна, но без примера разговор не предметный 


