Перейти к содержанию
    

Плавный переход C -> C++ под МК

40 минут назад, Forger сказал:

Конечно нет ) Иначе будет беда )) повторюсь - в самом cpp файле реализации этого класса, это внутренние static классы или данные, что угодно, к чему нельзя обратиться через extern.

Как Вы разобьете определение одного и того же класса на несколько частей? Одна в хедере другая в файле реализации. Вот Вы пишете

3 часа назад, Forger сказал:
// Communication.hpp

class Communication : public Module
{
public:
	Communication() { name = const_cast<char*>("Communication"); }

	static struct Signal
	{
		struct
		{
			Delegate<bool(SensorIndex)> isActive;
		} digitalInputs;

		struct
		{
			Delegate<void(ChannelIndex)> on;
			Delegate<void(ChannelIndex)> off;
		} digitalOutputs;

		struct
		{
			Delegate<Voltage()> 	getMainValveVoltage;
		} analogInputs;

	} signal;

	static Communication & getInstance();
};


Где и кто такой name, например? Очевидно, это некий приватный элемент наследуемого Module, потроха которого представлены в подключаемом хедере Communication.hpp или каком-то еще, или просто банально "около" класса Communication определен класс Module. Это вот ни разу не "отделение" реализации от интерфейса. Это просто синтаксический способ упрятать шелуху классов подальше, при этом, если гипотетически нужно кому-то собрать статическую библиотеку какого-нибудь функционала, все эти хедеры с кучей наследований друг друга должны быть также предоставлены. А я преследую цель максимально упрощенного набора файлов: хедер с интерфейсом и набор файлов .cpp реализации. В хедере ничего "лишнего", т.к. исходники я могу вообще собрать в статическую библиотеку и передать вместо .cpp.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, Forger сказал:
Communication() { name = const_cast<char*>("Communication"); }

а какого рожна class Communication изменяет члены класса Module без гетера на прямую? не вы ли тут с пеной у рта про доступ до членов только через гетеры?

Скажете: name - это protected. Меня учили писать без protected. Вернее, как я только его ставил - били по рукам. В контексте наследников от Module, protected - этот тоже самое что public. Т.е. вся родня может менять name. Ну у меня 160 родственников(наследников) и 2 чужака в деревне. 160 жителей могут залезть мне в кошелёк, а 2 нет. Это тоже самое, что все могут.

поэтому вместо protected меня приучили определиться, где должен быть name и закрыть его гетерами. Или же, если разрешил соседям жэну кому-то менять снаружи name ... то переноси его паблик.

34 минуты назад, Arlleex сказал:

Где и кто такой name, например?

убрать его в конструктор. Но Module.h всё равно - выньдапаложь со всем потрахами ))   

class Communication : public Module 
{ 
public: 
	Communication() : Module(const_cast<char*>("Communication")) {};
      // код
};
      
Изменено пользователем razrab83

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

41 minutes ago, Arlleex said:

де и кто такой name, например?

тут по хорошему должен быть метод смена имени, а не прямой доступ к полю имени (из секции protected класса Module). Но это чисто отладочное поле, в релизной версии не используется. Дойдут руки, исправлю )

41 minutes ago, Arlleex said:

Это просто синтаксический способ упрятать шелуху классов подальше, при этом, если гипотетически нужно кому-то собрать статическую библиотеку какого-нибудь функционала, все эти хедеры с кучей наследований друг друга должны быть также предоставлены.

А это плюсы, не шарп. Тут с этим ничего уже не поделать, увы

 

41 minutes ago, Arlleex said:

В хедере ничего "лишнего", т.к. исходники я могу вообще собрать в статическую библиотеку и передать вместо .cpp.

например класс Module у меня вообще относится к общей ко всем проектам библиотеке (Common), поэтому подключен только тут, где на него ссылаются, больше нигде.

Спрятать все невозможно, да и так ли это прям нужно?

Кстати, Communication тут ни как может быть библиотекой, это целиком уникальный модуль, который как раз и реализует функционал проекта, точнее его соотв. часть, есть и другие модули, связанные друг с другом строго делегатами.

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

 

8 minutes ago, razrab83 said:

Скажете: name - это protected. Меня учили писать без protected.

Есть ситуации, где без protected полей ну никак не обойтись (выше не тот случай, тут можно сеттер всунуть). Такие костыли реализуется как правило один раз и очень глубоко прячутся.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 minutes ago, razrab83 said:

убрать его в конструктор.

дойдут руки сделаю так, тут setName как раз protected из Module, такая запись мне кажется менее перегруженной "значками" ))  Исключительно, вкусовщина )

 Communication() { setName("Communication"); }

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

30 минут назад, Forger сказал:

нужно использовать, это вполне рабочее решение.

ну если только для такой вкусовщины, типа такой

Communication() { setName("Communication"); }

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 26.06.2024 в 16:52, Arlleex сказал:
Communication() { name = const_cast<char*>("Communication"); }

вангую, что name, это  char* Module::name; Иначе, зачем бы приводить const char* к char*? Тут уже проблема. 

В 26.06.2024 в 17:53, Forger сказал:

такая запись мне кажется менее перегруженной "значками" ))  Исключительно, вкусовщина )

 Communication() { setName("Communication"); }

такая запись во 1-х protected использует, во 2-х в внутри steName всё тоже const char* к char* приводиться. А не лучше  бы ли делать const char* Module::name? 

Communication() : Module("Communication") {}; - ещё менее перегруженная запись, чем c setName(), не требует protected, не нужно на константную строку ссылаться через неконстантный указатель.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 minutes ago, razrab83 said:

протектед методы не нужны и не оправданы. 

еще как оправданы, т.к. такие методы доступны только наследникам, это очень удобный механизм защитить методы от кого попало и только наследников и такой код проще читать (по крайней мере мне)

поля понятно, нельзя делать не приватными, это опасно, нужны сеттеры/геттеры

Если вы не используете иерархию классов в проектах (наследование), то конечно это не так важно.

 

10 minutes ago, razrab83 said:

как я предложил

У всех свои способы сделать код читаемым прежде всего для себя любимого. Свой код я читаю сам и чем он проще, тем благодарнее я сам себе. Ваш вариант мне кажется более громозким и менее читаемым, чем я привел свой вариант. Не настаиваю на своем решении, это просто вариант из многих. Мне абсолютно до лампочки, кто как для себя пишет код, но только, если мне никогда не придется чужой код применять у себя ))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

29 минут назад, Forger сказал:

тут setName как раз protected из Module, такая запись мне кажется менее перегруженной "значками" ))  Исключительно, вкусовщина )

если значки не нравятся, то 

Communication() : Module("Communication"){} - а в конструкторе Module значки, как и в setName

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, juvf said:

вангую, что name, это  char* Module::name;

это вообще отладочное поле, сделано лишь бы работало, дойдут руки, переделаю, ни на что не влияет, анахронизм от старых версий

знал бы, что именно эта строка вызовет такой батхёрт, удалил бы из куска кода,

1 minute ago, razrab83 said:

Communication() : Module("Communication"){}

это все сугубо индивидуальная вкусовщина, кто как привык и кому как удобнее, поэтому предлагаю сменить тему

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 минуты назад, Forger сказал:

Если вы не используете иерархию классов в проектах (наследование)

я использую иерархию классов. наследование и прочие плюшки ООП. Не использую protected ни для членов, ни для методов. Для меня, если кроме меня кто-то может использовать мой метод (или мои данные) - это тоже что кто попало. Я не настаиваю на правильности моего подхода. Делайте как вам удобно. Я про себя говорю. Отучили меня от протектед. Очень полезно.  

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, razrab83 said:

Отучили меня от протектед.

У меня есть ситуации, где все попытки перевести редкие методы (и даже очень редко поля) protected в секцию private создают массу проблем и делают код слишком громозким и даже медленным, это касается редких случаев, но они увы бывают.

Конечно, можно наоборот выносить protected методы в public, но это перебор. Что-то среднее как раз кстати.

Все это касается низкоуровневого кода, внизу иерархии. Выше такое уже не требуется.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

1 час назад, Arlleex сказал:

Как Вы разобьете определение одного и того же класса на несколько частей? Одна в хедере другая в файле реализации.

Теоретически это возможно. Даже возможно в несколько .cpp

 

 

Снимок экрана 2024-06-26 194640.jpg

Изменено пользователем EdgeAligned

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, razrab83 сказал:

Не использую protected ни для членов, ни для методов

Proteted - это область видимости в первом уровне наследования. Как раз хороший способ ускорить работу с полями или методами класса, в то же время закрыв их прямое изменение (вызов) 

 

Снимок экрана 2024-06-26 220935.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, EdgeAligned сказал:

Теоретически это возможно. Даже возможно в несколько .cpp

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

Если бы была возможность дробить определение класса (как, например, namespace), и выносить интерфейсную часть в хедер, а все темные дела в .cpp, то был бы такой же эффект. Но так сделать нельзя. Ослиные уши в виде прототипов приватных функций, да и сами приватные данные, будут видны в определении класса, т.е. в хедере.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А, про это... Ну есть еще множественное наследование, когда класс может наследоваться от нескольких базовых, с различными комбинациями видимости. Да, наследование так же может иметь три типа видимости.
Впрочем, лично я не заморачиваюсь постройкой того, на что комитет по ++ просто забил. Поскольку пишу только для себя и не предполагаю, что моя писанина вообще будет кому-то нужна, ибо такого в инете щас дофига и больше. Если же писать "для всех", то в идеале должны быть закрытые библиотеки в виде файлов типа .a или как-то так (забыл, как называется). Я раньше немного копал эту тему, но лично мне она не нужна была, поэтому дальше развивать её не стал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...