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

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

3 hours ago, EdgeAligned said:

Еще одна проблема, оставшаяся еще со времён Си - динамическое распределение памяти.

По-моему аллокатор дин. памяти не относится к языку как таковому, что в плюсах, что в си используется вызов библиотечных malloc/free и реже других.

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

За основу взят TLSF как есть, но с немного другими настройками, особенно на контроллерах с мелким озу.

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

 

 

 

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


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

21 час назад, tonyk_av сказал:

А как же наследование? Как без него?

Наследование в C++ прилеплено только лишь и потому, что язык преследует ООП-парадигму. Без наследования была бы не возможна концепция позднего связывания. И да - без наследования - легко. В Си не было никаких наследований и там не возникало вопросов "как без него".
 

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

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

Для толстых проектов типа каких-то CAD-ов, геймдева и т.д. это вполне может пригодиться, соглашусь.

18 часов назад, Forger сказал:

По-моему аллокатор дин. памяти не относится к языку как таковому, что в плюсах, что в си используется вызов библиотечных malloc/free и реже других.

Не так. В плюсах ключевые слова new и delete зарезервированы как раз для управления динамическим выделением памяти. В Си вызывали malloc/free - а это функции. Самые обыкновенные. Так что да - в плюсах вполне однозначно изначально был заложен механизм работы с динамической памятью на уровне синтаксиса операций.

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


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

45 minutes ago, Arlleex said:

Не так. В плюсах ключевые слова new и delete зарезервированы как раз для управления динамическим выделением памяти. В Си вызывали malloc/free - а это функции. Самые обыкновенные.

Вы не правы, эти самые new/delete как раз и вызывают библиотечные malloc/free и др. Если не верите, сделайте свои пустые заглушки на эти библиотечные функции и убедитесь лично под отладчиком.

Я поэтому и переделал их, что при вызове new/delete используются по-умолчанию слишком простые и рисковые библиотечные malloc/free.

Благо библитека позволяет чуть ли не все переписать под себя как угодно. В этом плане плюсы никуда не ушли от си

45 minutes ago, Arlleex said:

Так что да - в плюсах вполне однозначно изначально был заложен механизм работы с динамической памятью на уровне синтаксиса операций.

видимо мы говорим о несколько разных вещах )

я пришел к совершенно простому для меня объяснению - плюсы это по сути НАДСТРОЙКА на голым си, а никак не замена целиком.

А вот с C# ситуация с дин памятью как раз в корне была изменена и уже такие мои "фокусы" вряд ли прокатят (

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


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

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

Вы не правы, эти самые new/delete как раз и вызывают библиотечные malloc/free и др. Если не верите, сделайте свои пустые заглушки на эти библиотечные функции и убедитесь лично под отладчиком.

Я поэтому и переделал их, что при вызове new/delete используются по-умолчанию слишком простые и рисковые библиотечные malloc/free.

Благо библитека позволяет чуть ли не все переписать под себя как угодно. В этом плане плюсы никуда не ушли от си

Без разницы что они там вызывают. Факт есть факт - new, delete - такие же нативные операции среди ключевых слов языка, как и всякие там sizeof. Не нужно отрицать очевидное. Иначе в плюсах могли тупо оставить вызовы маллока функциями, как в си.

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


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

Just now, Arlleex said:

Факт есть факт - new, delete - такие же нативные операции среди ключевых слов языка, как и всякие там sizeof.

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

1 minute ago, Arlleex said:

Без разницы что они там вызывают.

Это очень важно, если вы собрались активно пользовать дин память (особенно STL), то без полного контроля кучи очень велик риск потерять контроль над проектом

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

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


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

43 minutes ago, Arlleex said:

Наследование в C++ прилеплено только лишь и потому, что язык преследует ООП-парадигму. Без наследования была бы не возможна концепция позднего связывания. И да - без наследования - легко.

Значит, не осознали его значимость и нужность по причине того, что пока не сформировалось объектное мышление. Простой пример: UART. Есть текстовый терминал, работающий по EIA-232, есть Модбас/RTU-мастер, работающий через EIA-485. Когда попробуете выделить у них общее, то с удивлением обнаружите, что у них на 95% общий код, и что создать для них общего предка становится естественным. Ну а разницу вынести в наследников. Так что тут я категорически не соглашусь, что наследование "в С++ прилеплено".

Первое, что попалось на глаза:

class FPU_device : protected IRQ
{
    public:

        FPU_device( void );
        ~FPU_device( void );

    private:

        // Обработка исключений устройства с плавающнй точкой.
        virtual void IRQ_Handler( void );
};

То есть, следуя ОО-пардигме, любой объект, желающий обрабатывать прерывания, должен быть наследником класса IRQ и определить виртуальный метод IRQ_Handler().

class IRQ
{
	....

    protected:

        IRQ( void );
        virtual ~IRQ( void );

        //----------------------------------------------------------------------
        // Обработчик прерывания.
        virtual void IRQ_Handler( void ) = 0;

	....
};

 

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


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

В принципе, new/delete могут быть перегружены лдя классов.

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

То есть:

class Base {
public:
	void FooBase()
	{
		b = 0;
	}

protected:
	int x;

private:
	int b;
};

class A: public Base {
public:
	void FooA()
	{
		FooBase();
		x = 0;
//		b = 40; // запрещено
	}
};

class B: private A {
public:
	void FooB()
	{
		FooA();
		FooBase();
		x = 10;
	}
};

.....
  	A a;
	a.FooA();
	a.FooBase();
//	a.x = 5 // запрещено
//	a.b = 77; // запрещено

	B b;
	b.FooB();
//	b.FooBase(); // запрещено
//	b.x = 4; // запрещено

 

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


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

18 minutes ago, Arlleex said:

Без разницы что они там вызывают.

А вот и не без разницы! new-delete учитывают _тип_ объекта в отличие от банальных alloc-free. Более, того ещё и с учётом сигнатуры, что явно не доступно в С.

EdgeAligned, мы с тобой одновременно об одном и том же, только чуть разными словами. 🙂

 

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


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

14 minutes ago, EdgeAligned said:

В принципе, new/delete могут быть перегружены лдя классов.

можно перегрузить даже "глобальный" new/delete, это заложено в базе языка, но это не всегда и порой совсем не удобно

в моей ситуации пришлось "лезть глубже" с перегрузками под несколько другой причине, но вряд ли кому-то это будет интересно )

 

15 minutes ago, tonyk_av said:

определить виртуальный метод IRQ_Handler().

причем у вас о чисто виртуальный (= 0), что требует обязательной реализации этого метода в наследнике, то очень удобно, согласитесь ))

довольно часто использую такой механим, очень полезный функционал, особенно для создания базовых интерфейсных классов (что типа паттерн "фасад"), через которые идет общение с наследниками

второй полезный плюс такого класса - невозможно создать его экземпляр без наследования,

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


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

и еще одна фича - объекты можно передавать по типу базового класса. Вкупе с чисто виртуальным базовым классом это дает интересную возможность.

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


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

20 minutes ago, EdgeAligned said:

и еще одна фича - объекты можно передавать по типу базового класса. Вкупе с чисто виртуальным базовым классом это дает интересную возможность.

дык именно так поэтому такие зачастую чисто виртуальные классы и называют "классами-интерфейсами" )

например, базовый класс того же порта UART, а уже его реализация в т.ч. чисто программный UART - снаружи никому не видна

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

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


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

А вот в этом как раз косяк языка. Понятие "интерфейс модуля" в нем нет совсем. Была некая попытка сделать его по-сишному через пару .cpp/.hpp и вынос реализаций методов вне класса в .cpp, но сделано было глючно - в случае с шаблонным классом эта затея уже не работает. Поэтому наследование от чисто виртуального базового класса для реализации интерфейса - в принципе это костыль. 

Еще один косяк языка, как следствие предыдущего - все инклюды и дефайны, написаные в .hpp, становятся видимыми везде при подключении файла. И хотя с дефайнами изобрели обходной костыль, но с инклюдами косяк так и остался.

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


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

1 hour ago, EdgeAligned said:

Еще один косяк языка, как следствие предыдущего - все инклюды и дефайны, написаные в .hpp, становятся видимыми везде при подключении файла

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

Впрочем, никто не заставляет добавлять в hpp файл все подряд ))

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

кстати, про дефайны - этот "атавизм" можно отчасти решить заменой на constexpr, где это возможно

 

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


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

Я про то, что стоит только в каком-нить gpio.hpp подключить какой-нить "stm32f10x.h" и подключить этот gpio.hpp, так сразу stm32f10x.h становится видимым везде. Аналогично и с дефайнами, которые можно использовать для условной компиляции. И хорошо, что есть #undef, это хоть как-то спасает. Однако, действие constexpr аналогичным образом отменить нельзя.
В общем, разграничение видимости этих моментов уже десятки лет остается недопиленным. Печалька. Я ж говорю - ядро языка не совершенствуется, "детские болячки" не исправлены, а тянутся годами, комитетчики на них забили и увлеклись нашлепыванием STL, которая тоже тянет всё те же косяки.

А касательно топикстартера и его "пути воина" - блин, за 3 года и почти 60 страниц темы можно было уже выучить ++ от и до. Однако, у топикстартера какой-то бессистемный подход, пропускает базовые моменты, потому куча непоняток и нет большого прогресса. За всё время - только namespace, class/struct в самом базовом понятии и немного шаблонов. Стоило ли начинать?

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


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

2 hours ago, EdgeAligned said:

Я про то, что стоит только в каком-нить gpio.hpp подключить какой-нить "stm32f10x.h" и подключить этот gpio.hpp, так сразу stm32f10x.h становится видимым везде.

Я поступаю чуть иначе: этот stm32f10x.h подключаю внутри CPP, а внутри HPP оставляю только то, что необходимо для работы с ним.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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