реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Последовательность вызова конструкторов, глобальных объектов при инициализации (ARM)
Andy Mozzhevilov
сообщение Sep 23 2010, 07:33
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206



Вопрос, можно ли как-то средствами расширения языка, а также параметрами и скриптами линкера (IAR ARM 5.xx) задать посделовательность инициализации (вызовов конструкторов) глобальных объектов?
То есть, например:
Код
class TSlon
{
....
};

class TMamont
{
....
};

TSlon    Slon;   // Этот объект должен быть инициализирован первым при запуске
TMamont  Mamont; // Этот объект должен быть инициализирован вторым при запуске



--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
dxp
сообщение Sep 23 2010, 08:21
Сообщение #2


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Andy Mozzhevilov @ Sep 23 2010, 14:33) *
Вопрос, можно ли как-то средствами расширения языка, а также параметрами и скриптами линкера (IAR ARM 5.xx) задать посделовательность инициализации (вызовов конструкторов) глобальных объектов?

Если объекты объявляются в одной единице трансляции, то гарантируется тот порядок их создания, в котором они объявлены.

TSlon slon;
TMamont mamont;

slon будет создан первым, mamont за ним.

Если объекты объявлены в разных единицах трансляции, то тут порядок создания не гарантируется. Избавиться от зависимости создания в этом случае можно дополнительными ухищрениями - например, с помощью singleton'а.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Sep 23 2010, 09:23
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



В свое время отказался от раздумий по очередности вызова конструкторов глобальных объектов.
Сейчас использую следующую схему:
1) Собственно сам конструктор
2) Этап Init()
3) Этам Run()

В самом конструкторе объект ведет себя изолированно от внешнего мира. Категорически не допускается взаимодействия с другими объектами (они у меня зачастую в другой единицы трансляции)
На этапе Init() происходит "налаживание связей" между объектами (обмен информацией, финальная инициализация и тд). На этапе Run() запускаются таски, включаются прерывания и тд.
Этапы Init и Run запускаются из main, что гарантирует создание глобальных объектов к этому моменту.

Код
///@function main()
///Main function
int main()
{
  * * *
  ClSystemService::Instance()->InitServices();
  ClSystemService::Instance()->RunServices();
  * * *
}


Либо возможен другой вариант: использование паттерна Singleton. Тогда обращение к объекту будет гарантировать его наличие smile.gif
Go to the top of the page
 
+Quote Post
Andy Mozzhevilov
сообщение Sep 23 2010, 14:17
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 877
Регистрация: 26-01-05
Из: Екатеринбург
Пользователь №: 2 206



Цитата(Dima_G @ Sep 23 2010, 13:23) *
На этапе Init() происходит "налаживание связей" между объектами (обмен информацией, финальная инициализация и тд).

Вызывать отдельно Инит для каждого объекта - это надо не забыть об этом.
Иногда (и зачастую) объект создается просто глобально, а потом живет своей жизнью. Дополнительные init и run - потенциальная возможность забыть их сделать, соответственно допустить ошибку, которую потом возможно будет трудно поймать.
Объект, который мне нужно заинитить первым - он один в системе.
Точнее нужно вызвать инициализацию ОС, чтобы в конструкторах всех глобальных объектов можно было использовать функции ОС по созданию сервисов (семафоров, очередей и т.п.). Иначе нужно разносить в каждом классе создание объекта и его инициализацию - это достаточно трудоемко.


--------------------
Пасу котов...
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Sep 23 2010, 15:21
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Цитата(Andy Mozzhevilov @ Sep 23 2010, 21:17) *
Вызывать отдельно Инит для каждого объекта - это надо не забыть об этом.


На самом деле я маленько слукавил smile.gif Если на пальцах, то у меня юсается следующая архитектура:
1) Реализована система широковещательных посылок. Те посылка (объект) не имеет адресата, она лишь имеет характеристику "тип посылки". (те посылки могут иметь тип "int", тип "ClSlon" и тд - типом посылки может быть любой тип, который может быть параметром шаблона (особенности реализации)). Объекты могут подписываться на определенный тип сообщений. Адресант сообщений ничего не знает об адресатах.
2) Есть сообщения типа "Init", "Run"
3) Все сервисы наследуются от базового класса, который подписан на сообщения Init, Run и при их получении вызывает свои виртульные методы.

Соответственно, в main-е я просто посылаю широковещательные сообщения, а сервисы их ловят и происходят необходимые действия. Таким образом я исключаю возможность "забыть проинициализировать" объект. Да и вообще - я в main-е ничего о них не знаю

Цитата(Andy Mozzhevilov @ Sep 23 2010, 21:17) *
Объект, который мне нужно заинитить первым - он один в системе.
Точнее нужно вызвать инициализацию ОС, чтобы в конструкторах всех глобальных объектов можно было использовать функции ОС по созданию сервисов (семафоров, очередей и т.п.).


Тогда прямая дорога - использование синглетонов. Самый простейший (не самый лучший) способ:

Код
template <class T>
class TClSingleton
{
  public:
    inline static T& Instance()
    {
      static T clObj_;
      retrun T;
    }
};

class ClSingleObject: public TClSingleton<ClSingleObject>
{
  frined class TClSingleton<ClSingleObject>;
  
  private:
    ClSingleObject(){...}
    ClSingleObject(const ClSingleObject&){..}

  public:
    void fun();
};

* * *
ClSingleObject::Instance()->fun();
* * *


В крайней строчке мы вызываем метод объекта, причем не имея самого объекта. Он будет создан при первом вызове и не будет продублирован при последующих.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 23 2010, 16:12
Сообщение #6


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Dima_G @ Sep 23 2010, 21:21) *
Самый простейший (не самый лучший) способ:


Что-то как-то сложно. Я делаю проще:

singleton.h:
Код
#ifndef SINGLETON_H_
#define SINGLETON_H_

template<typename T> class singleton
{
public:
    static T& Instance() __attribute__((__noinline__))
    {
        static T instance;
        return instance;
    }
};
#endif /* SINGLETON_H_ */

А определение
Код
uart_t uart;

заменяю на
Код
uart_t& uart = singleton<uart_t>::Instance();


И телемаркет smile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Dima_G
сообщение Sep 23 2010, 16:48
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 279
Регистрация: 2-07-08
Из: Новосибирск
Пользователь №: 38 699



Цитата(AHTOXA @ Sep 23 2010, 23:12) *
Что-то как-то сложно. Я делаю проще:

Да то же самое smile.gif
А, если не секрет, почему noinline?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Sep 23 2010, 17:09
Сообщение #8


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Dima_G @ Sep 23 2010, 22:48) *
А, если не секрет, почему noinline?


Компилятор ругался, что не удалось заинлайнить.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
gladov
сообщение Oct 12 2010, 18:49
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 169
Регистрация: 10-11-05
Из: Воронеж
Пользователь №: 10 687



Цитата(AHTOXA @ Sep 23 2010, 20:12) *
Что-то как-то сложно. Я делаю проще:

...

И телемаркет smile.gif


А дело в том, что паттерн singleton по своей сути должен гарантировать что в системе будет существовать только один объект данного класса. Если же не объявить упомянутый в примере uart_t как наследник singleton'a и не сделать у него приватных конструкторов, как это сделано у Dima_G, то компилятор разрешит сделать так:
Код
uart_t *U1 = new uart_t;
uart_t *U2 = new uart_t;
uart_t& U3 = singleton<uart_t>::Instance();

Получим 3 объекта класса uart_t. Значит автор кода должен помнить, что создавать объеты данного класса напрямую низя.
В варианте от Dima_G на уровне копилятора гарантируется, что объект класса ClSingleObject будет единственный и наплодить других не получится.
Go to the top of the page
 
+Quote Post
shreck
сообщение Oct 13 2010, 02:14
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 24-06-06
Из: Томск
Пользователь №: 18 328



В догонку.
Цитата(AHTOXA @ Sep 23 2010, 23:12) *
А определение
Код
...

заменяю на
Код
uart_t& uart = singleton<uart_t>::Instance();

И телемаркет smile.gif


Использование ссылки uart, проинициализированной динамически - может быть засада. Насколько я помню, такая инициализация выполняется чуть ли не самой последней. И, например, конструктор некоторого объекта, использующего в своем теле uart, обломается.
Синглетоны на то и синглетоны. Обращаться к ним всегда надо именно через instance().
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Oct 13 2010, 08:01
Сообщение #11


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(gladov @ Oct 13 2010, 00:49) *
В варианте от Dima_G на уровне копилятора гарантируется, что объект класса ClSingleObject будет единственный и наплодить других не получится.


Понятно, спасибо за разъяснения.

Цитата(shreck @ Oct 13 2010, 08:14) *
Использование ссылки uart, проинициализированной динамически - может быть засада. Насколько я помню, такая инициализация выполняется чуть ли не самой последней. И, например, конструктор некоторого объекта, использующего в своем теле uart, обломается.


Да, вы правы. Я забыл упомянуть, что в конструкторах я использую локальную ссылку, и инициализирую её отдельно. А та, глобальная ссылка - это уже на потом, чтоб не менять остальной код, который раньше работал с обычной переменной uart smile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 14:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.0148 секунд с 7
ELECTRONIX ©2004-2016