spongebob 0 21 декабря, 2010 Опубликовано 21 декабря, 2010 · Жалоба Всем привет! Подскажите, пожалуйста, в каком порядке создаются глобальные объекты программы (экземпляры классов и переменные простых типов)? В том, в котором они перечислены при объявлении? Компилятор WinAVR. Имеет ли значение вид компилятора C++? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 21 декабря, 2010 Опубликовано 21 декабря, 2010 · Жалоба Порядок вызова глобальных конструкторов не регламентирован. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spongebob 0 21 декабря, 2010 Опубликовано 21 декабря, 2010 · Жалоба Порядок вызова глобальных конструкторов не регламентирован. Т. е., получается, что мы не знаем, какой объект создастся первым, а какой последним? А если, к примеру, объект 2 зависит от объекта 1 и объект 1 должен быть создан до объекта 2 (применительно к классам)? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kurtis 0 21 декабря, 2010 Опубликовано 21 декабря, 2010 · Жалоба Именно, даже существуют методики, которые гарантируют что обьект А будет создан раньше обьекта Б. А вообще, если у вас сильная зависимость между классами, то возможно, следует пересмотреть иерархию классов. Чтоб не быть голословным, вот пример: class SomeFoo { public: int func1() { ... }; }; /* функция возвращает ссылку на обьект типа SomeFoo */ SomeFoo& some_func() { /* статически создаем обьект типа SomeFoo */ static SomeFoo myClass; /* возвращаем ссылку на статический обьект */ return myClass; } class SomeOtherClass { public: my_other_func() { int some_value = some_func().func1(); }; }; надеюсь из кода все понятно. Общий смысл в том, что в функции создается статический объект, ссылка на который, потом возвращается туда куда нам надо. Мне такой трюк нужен был только однажды, да и то, потом как-то обошлось, поменял немного архитектуру. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 21 декабря, 2010 Опубликовано 21 декабря, 2010 · Жалоба в каком порядке создаются глобальные объекты программыВ том порядке, в котором линкер сложит секции *(.ctors*). В пределах одной единицы компиляции получаются в порядке объявления. Между единицами компиляции - можно сортировать по имени файла, можно еще по каким-то признакам (точно не помню). Все это описывается строкой скрипта KEEP(SORT(*)(.ctors)). Описание - (в том числе и сортировок) - в документации на линкер директива SORT(). Но все это нестандандартно и от лукавого, закладываться на это - делать код неперносимым на другой компилятор. Нужна ли такая переносимость если gcc есть под все процы с которыми работаете - решать вам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 21 декабря, 2010 Опубликовано 21 декабря, 2010 · Жалоба Это к сожалению тонкости конкретного компилятора и я бы на них не полагался. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spongebob 0 21 декабря, 2010 Опубликовано 21 декабря, 2010 · Жалоба Фактически, ситуация следующая (возможно, посоветуете что-нибудь лучше). Допустим, в проекте есть несколько глобальных переменных, которые используются в нескольких модулях. Мы преследуем две цели: задать порядок создания и облегчить включение глобальных переменных в несколько модулей. Создаем "x.cpp", в котором определяем все наши глобальные объекты, в файле "x.hpp" объявляем все эти объекты, используя директиву "extern". Далее инклудим файл "x.hpp" в нужные нам .cpp. Но все это нестандандартно и от лукавого Понимаю теперь, будем от этого уходить :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 22 декабря, 2010 Опубликовано 22 декабря, 2010 · Жалоба Фактически, ситуация следующая (возможно, посоветуете что-нибудь лучше). Допустим, в проекте есть несколько глобальных переменных, которые используются в нескольких модулях. Мы преследуем две цели: задать порядок создания и облегчить включение глобальных переменных в несколько модулей. Создаем "x.cpp", в котором определяем все наши глобальные объекты, в файле "x.hpp" объявляем все эти объекты, используя директиву "extern". Далее инклудим файл "x.hpp" в нужные нам .cpp. Да, для одной единицы трансляции гарантируется порядок создания объектов. Если зависимые объекты размещать в одной единице трансляции, то проблем нет. В противном случае надо применять разного рода трюки - например, уже не раз тут (на форуме) упоминавшийся singleton. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 22 декабря, 2010 Опубликовано 22 декабря, 2010 · Жалоба Да, для одной единицы трансляции гарантируется порядок создания объектов. Если зависимые объекты размещать в одной единице трансляции, то проблем нет. В противном случае надо применять разного рода трюки - например, уже не раз тут (на форуме) упоминавшийся singleton. singleton гарантирует, что объект будет создан только один раз и мы сами должны вызвать его Instance в нужном месте и в нужное время. Таким образом это не есть глобальный объект в обычном понимании, конструктор которого компилятор сам помещает в специальную таблицу, обеспечивая вызов конструкторов до main(). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 22 декабря, 2010 Опубликовано 22 декабря, 2010 · Жалоба Общий смысл в том, что в функции создается статический объект, ссылка на который, потом возвращается туда куда нам надо.Всё так, только инициализируется этот объект именно в момент вызова функции (собственно, для гарантии наличия, функция-то может вызываться и из других конструкторов), что тянет за собой дополнительную флаговую переменную со смыслом bool initialised; и соответствующий код. А при отсутствии (это я уже о gcc) -fno-threadsafe-statics там ещё и мьютексы __cxa_guard_* В мелких мелкоконтроллерах жаба давить начинает. Мне такой трюк нужен был только однажды, да и то, потом как-то обошлось, поменял немного архитектуру. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 22 декабря, 2010 Опубликовано 22 декабря, 2010 · Жалоба singleton гарантирует, что объект будет создан только один раз и мы сами должны вызвать его Instance в нужном месте и в нужное время. Таким образом это не есть глобальный объект в обычном понимании, конструктор которого компилятор сам помещает в специальную таблицу, обеспечивая вызов конструкторов до main(). Конечно. Это просто один из путей обхода проблем, возникающих от неопределенности порядка создания объектов, объявленных в разных единицах трансляции. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
spongebob 0 23 декабря, 2010 Опубликовано 23 декабря, 2010 · Жалоба Всем спасибо :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться