![]() |
Модераторы: Daevaorn |
![]() ![]() ![]() |
|
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
Такой вопрос.
Видел как один чел использовал в программе указатель на статическую переменную из функции. То есть есть просто функция (не метод) в одном из файлов проекта. Он из нее возвращает указатель на внутреннюю статическую переменную. Я у себя проверил - работает. Функцию имплементировал в одном из файлов проекта, в другом в мэйн ее использовал. В связи с этим вопрос - не понятно. Есть ли это в ANSI С, то есть работает ли во всех компиляторах ? То есть по своему назначению внутренняя статическая переменная служит для нужд функции, но никак не для работы наруже. Вообще есть правило, что область видимости статической переменной ограничивается файлом, где она объявлена. Получается, что передавая на нее поинтер это правило можно обойти, и вообще сливается грань между внутренней и глобальной статической переменной. Я пришел к мнению, что использовать такое, наверное, можно, но не корректно... Кто что думает - интрересно почитать. |
|||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
я использую, там где считаю необходимым, ничего незаконного не вижу в этом,
пример:
|
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
Так часто реализуют шаблон проектирования "синглтон"
|
|||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
||||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
это служит намного более удобным заменителем глобальной переменной
наруже она нужна, но сделано так, что полностью контролируется доступ к ней, а не бесконстрольное считывание/запись в случае просто глобальной переменной |
||||
|
|||||
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
В этом варианте все в порядке - там возвращается статическая переменная класса, а не внутренняя переменная метода.
Нигде в литературе не видел, чтобы возвращалась внутренняя статическая. |
|||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
||||
|
||||
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
В твоем
Добавлено @ 14:19
Это сообщение отредактировал(а) Random13 - 4.12.2007, 14:20 |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
ну вот увидел. |
|||
|
||||
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
Если я увидел, что кто-то, что то делает - то не значит, что это правильно и корректно и везде будет работать.
В литературе по этому поводу ничего не читал никогда. |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Возврат ссылки или указателя на статическую переменную, объявленную внутри функции совершенно корректен. На конкретный пункт стандарта сослаться не могу, но и в литературе ссылки встречаются. Например, у Майерса или у Саттера. Или описание реализации синглетона из книги банды четырех. Более того, это шикарный прием для обхода проблемы "инициализации вовремя": как известно, порядок инициализации нормальных (внешних) глобальных или статических переменных из разных единиц компиляции неопределен. И легального способа добиться, чтобы переменная A была инициализирована гарантированно раньше переменной B не существует - если они в разных модулях. Т.е. мы получим проблему, если инициализация A зависит от B. А если вместо глобальной переменной мы используем ссылку на статическую переменную внутри функции, то она гарантированно будет инициализирована ровно в момент первого вызова - т.е. когда нам надо. И это стандарт гарантирует. -------------------- ... |
|||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
||||
|
||||
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
А я скажу, что - это некорректно.
Мало кто чего говорит. Ну недоверчивый я такой, когда дело идет о таких вещах. Мне бы почитать где об этом. На душе бы полегчало. ![]() |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
Random13, тебе сказали, где читать.
|
|||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
||||
|
||||
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
Если возможность недокументированная, значит опасная. Если нет в ANSI, значит есть вероятность существования компилятора, в котором это не будет работать. И какие могут быть претензии к создателю компилятора при этом, если этого нет в стандарте ? Добавлено через 5 минут и 57 секунд Первое сомнение изложил. Второе, всегда в литературе почему-то работают с динамической памятью , где с указателем на статические внутренние переменные получается удобней. |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
чего это нет в стандарте? Там есть упоминание о том, что время жизни такой переменной - время выполнения программы? Есть. Значит она там будет всегда, когда бы мы к ней не обратились. Да она сама (статическая переменная) не видна вне функции, в которой объявлена, и против этого мы тоже не идем, мы ведь не пытаемся увеличить видимость переменной (дико звучит ![]() Что незаконного в действиях? теперь когда будешь говорить о недокументированности, уточняй, в каком именно месте мы расходимся с документацией ![]() |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
Статическая переменная внутри метода отличается от глобальной переменной(статической) только видимостью.
У Александресску хорошо описана эта проблема. Недостаток этого подхода(достоинство?) - тип переменной определен на этапе компиляции, и нельзя контролировать время жизни такой переменной. Могут быть траблы, если есть несколько статических переменных (не тривиальных типов) и одна обращается к другой в своем деструкторе, а та уже уничтожена. |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Это все в равной степени относится и к глобальным переменным. Собственно, статическая переменная внутри функции отличается только тем, что можно контролировать время создания. Насчет "Тип определен во время компиляции" - не совсем так: кто мешает иметь указатель и инициализировать его (по запросу) исходя из каких-либо условий? Элементарно, если понадобиться. Т.е. никаких отличий от любого другого полиморфного указателя. -------------------- ... |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
А разве деструкторы статических объектов вызываются не в порядке, обратном вызову конструкторов? Так реализовать проще, имхо.
|
|||
|
||||
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
Не совсем понятно. Все глобальные переменные инициализируются до мейн(), функцию любую можно вызвать только после входа в мейн(). Ну или до мэйн() можно при создании глобального объекта вызвать внешнюю функцию из конструктора. Тогда при чем тут порядок инициализации ? С тем же успехом можно либо в мэйн() вначале задать значение А, и В(А). Либо сделать это в той же функции при построении глобального объекта. В общем интересно. Как-нить может сам набреду на пример. ![]() |
|||
|
||||
zkv |
|
|||
![]() ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 2133 Регистрация: 23.7.2006 Где: Санкт-Петербург Репутация: 26 Всего: 92 |
Random13, имеется ввиду нечто подобное:
ну и по аналогии со статическими переменными та же история. |
|||
|
||||
bsa |
|
||||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
вот о чем речь: файл aaa.cpp:
|
||||||||||
|
|||||||||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Речь ведь идет не о вложенных напрямую объектах, а о том что переменная A в деструкторе за каким-то лешим лезет к переменной B, тоже статической. Т.к. порядок создания их не определен, точно так же не определен и порядок разрушения. То, что он обратный созданию, не спасает - при создании объекту A до объекта B может быть до лампочки.
Это был ответ bsa... про порядок вызова деструкторов ... Это сообщение отредактировал(а) Earnest - 4.12.2007, 16:47 -------------------- ... |
|||
|
||||
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
Это понятно. Не понятно как указатель на внутреннюю статическую переменную, ну или пусть на глобальную статическую поможет проблему очередности решить ?
|
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
По стандарту, статическая переменная внутри функции инициализируется при первом вызове этой функции. Т.е. если ты вызовешь эту функцию из конструктора другой глобальной переменной, то гарантированно наша статическая переменная будет уже готова к использованию.
-------------------- ... |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
При вызове указанного метода/функции статическая переменная содержащаяся в нем уже инициализирована. |
|||
|
||||
Earnest |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 5962 Регистрация: 17.6.2005 Где: Рязань Репутация: 53 Всего: 183 |
Более того, если функция не вызывается ни разу, переменная не будет инициализирована вообще. Что в некоторых случаях полезно.
-------------------- ... |
|||
|
||||
Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
никак он помогает решить проблему создания объекта по требованию... вообще, городить систему взаимодействующих между собой глобальных объектов - это плохое проектирование. |
|||
|
||||
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
А нельзя в этой самой функции инициализировать А, а следом за ним В ? Пусть не инициализировать, но присвоить им нужные значения ? |
|||
|
||||
Fazil6 |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
если бы тебе была понятна суть проблемы очередности создания, то было бы понятно как данный вариант эту проблему решает
|
||||
|
|||||
Random13 |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 116 Регистрация: 21.11.2007 Репутация: нет Всего: нет |
А если написать int getX() { return х; } у = getX(); Это не принудит построить х до у? Добавлено через 1 минуту и 32 секунды Нет, наверное вы правы не принудит по идее. Спасибо. Хороший тут форум живой - где вы раньше были ![]() Добавлено через 6 минут и 31 секунду Хотя в данном примере не передается указатель на статическую переменную - передается временная копия статической переменной ![]() |
|||
|
||||
Fazil6 |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1653 Регистрация: 3.5.2006 Где: Минск Репутация: 35 Всего: 60 |
||||
|
||||
baldina |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3433 Регистрация: 5.12.2007 Где: Москва Репутация: 32 Всего: 101 |
Ключевое слово static имеет различную семантику.
Для глобальных переменных означает ограничение области видимости единицей компиляции (т.е. cpp файлом). Считается устаревающим, рекомендуется для этого использовать неименованный namespace. Для переменных - членов класса означает, что переменная не дублируется в каждом объекте, а существует в единственном экземпляре. Собственно, все. По поводу правильности, законности и переносимости все уже ранее разъяснили. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "С++:Общие вопросы" | |
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |