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

 
 
 
Reply to this topicStart new topic
> Объекты в C++
spongebob
сообщение Dec 21 2010, 18:06
Сообщение #1


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

Группа: Участник
Сообщений: 126
Регистрация: 14-11-10
Пользователь №: 60 879



Всем привет!

Подскажите, пожалуйста, в каком порядке создаются глобальные объекты программы (экземпляры классов и переменные простых типов)?
В том, в котором они перечислены при объявлении?
Компилятор WinAVR.
Имеет ли значение вид компилятора C++?
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 21 2010, 18:17
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Порядок вызова глобальных конструкторов не регламентирован.
Go to the top of the page
 
+Quote Post
spongebob
сообщение Dec 21 2010, 18:50
Сообщение #3


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

Группа: Участник
Сообщений: 126
Регистрация: 14-11-10
Пользователь №: 60 879



Цитата(sergeeff @ Dec 22 2010, 00:17) *
Порядок вызова глобальных конструкторов не регламентирован.


Т. е., получается, что мы не знаем, какой объект создастся первым, а какой последним? А если, к примеру, объект 2 зависит от объекта 1 и объект 1 должен быть создан до объекта 2 (применительно к классам)?
Go to the top of the page
 
+Quote Post
kurtis
сообщение Dec 21 2010, 19:15
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 466
Регистрация: 21-06-05
Пользователь №: 6 205



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

Чтоб не быть голословным, вот пример:

Код
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();
        };
};


надеюсь из кода все понятно. Общий смысл в том, что в функции создается статический объект, ссылка на который, потом возвращается туда куда нам надо. Мне такой трюк нужен был только однажды, да и то, потом как-то обошлось, поменял немного архитектуру.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 21 2010, 19:19
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (spongebob @ Dec 21 2010, 23:06) *
в каком порядке создаются глобальные объекты программы
В том порядке, в котором линкер сложит секции *(.ctors*). В пределах одной единицы компиляции получаются в порядке объявления. Между единицами компиляции - можно сортировать по имени файла, можно еще по каким-то признакам (точно не помню). Все это описывается строкой скрипта KEEP(SORT(*)(.ctors)). Описание - (в том числе и сортировок) - в документации на линкер директива SORT(). Но все это нестандандартно и от лукавого, закладываться на это - делать код неперносимым на другой компилятор. Нужна ли такая переносимость если gcc есть под все процы с которыми работаете - решать вам.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 21 2010, 19:23
Сообщение #6


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Это к сожалению тонкости конкретного компилятора и я бы на них не полагался.
Go to the top of the page
 
+Quote Post
spongebob
сообщение Dec 21 2010, 19:44
Сообщение #7


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

Группа: Участник
Сообщений: 126
Регистрация: 14-11-10
Пользователь №: 60 879



Фактически, ситуация следующая (возможно, посоветуете что-нибудь лучше).
Допустим, в проекте есть несколько глобальных переменных, которые используются в нескольких модулях.
Мы преследуем две цели: задать порядок создания и облегчить включение глобальных переменных в несколько модулей.
Создаем "x.cpp", в котором определяем все наши глобальные объекты, в файле "x.hpp" объявляем все эти объекты, используя директиву "extern". Далее инклудим файл "x.hpp" в нужные нам .cpp.

Цитата
Но все это нестандандартно и от лукавого


Понимаю теперь, будем от этого уходить sm.gif
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 22 2010, 01:54
Сообщение #8


Adept
******

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



Цитата(spongebob @ Dec 22 2010, 04:44) *
Фактически, ситуация следующая (возможно, посоветуете что-нибудь лучше).
Допустим, в проекте есть несколько глобальных переменных, которые используются в нескольких модулях.
Мы преследуем две цели: задать порядок создания и облегчить включение глобальных переменных в несколько модулей.
Создаем "x.cpp", в котором определяем все наши глобальные объекты, в файле "x.hpp" объявляем все эти объекты, используя директиву "extern". Далее инклудим файл "x.hpp" в нужные нам .cpp.

Да, для одной единицы трансляции гарантируется порядок создания объектов. Если зависимые объекты размещать в одной единице трансляции, то проблем нет. В противном случае надо применять разного рода трюки - например, уже не раз тут (на форуме) упоминавшийся singleton.


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


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(dxp @ Dec 22 2010, 08:54) *
Да, для одной единицы трансляции гарантируется порядок создания объектов. Если зависимые объекты размещать в одной единице трансляции, то проблем нет. В противном случае надо применять разного рода трюки - например, уже не раз тут (на форуме) упоминавшийся singleton.


singleton гарантирует, что объект будет создан только один раз и мы сами должны вызвать его Instance в нужном месте и в нужное время. Таким образом это не есть глобальный объект в обычном понимании, конструктор которого компилятор сам помещает в специальную таблицу, обеспечивая вызов конструкторов до main().
Go to the top of the page
 
+Quote Post
ReAl
сообщение Dec 22 2010, 04:26
Сообщение #10


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(kurtis @ Dec 22 2010, 00:15) *
Общий смысл в том, что в функции создается статический объект, ссылка на который, потом возвращается туда куда нам надо.
Всё так, только инициализируется этот объект именно в момент вызова функции (собственно, для гарантии наличия, функция-то может вызываться и из других конструкторов), что тянет за собой дополнительную флаговую переменную со смыслом bool initialised; и соответствующий код. А при отсутствии (это я уже о gcc) -fno-threadsafe-statics там ещё и мьютексы __cxa_guard_*
В мелких мелкоконтроллерах жаба давить начинает.
Цитата(kurtis @ Dec 22 2010, 00:15) *
Мне такой трюк нужен был только однажды, да и то, потом как-то обошлось, поменял немного архитектуру.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
dxp
сообщение Dec 22 2010, 08:56
Сообщение #11


Adept
******

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



Цитата(sergeeff @ Dec 22 2010, 13:00) *
singleton гарантирует, что объект будет создан только один раз и мы сами должны вызвать его Instance в нужном месте и в нужное время. Таким образом это не есть глобальный объект в обычном понимании, конструктор которого компилятор сам помещает в специальную таблицу, обеспечивая вызов конструкторов до main().

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


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


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

Группа: Участник
Сообщений: 126
Регистрация: 14-11-10
Пользователь №: 60 879



Всем спасибо sm.gif
Go to the top of the page
 
+Quote Post

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

 


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


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