Здравствуйте, Андрей Коростелев, Вы писали:
АК>Здравствуйте, slavo, Вы писали:
S>>День добрый, как гарантированно создать экземпляр класс CClass раньше, чем создастся экземпляр любого другого класса?
АК>Идиома Schwarz Counter позволяет обеспечить гарантированный порядок инициализации объектов со static storage duration.
Только там откровенный ляп:
class StreamInitializer {
public:
StreamInitializer ();
~StreamInitializer ();
} initializer; //Note object here in the header.
Объект initializer должен быть статическим, в противном случае линкер надает по рукам за множественное определение одного и того же объекта в разных единицах трансляции. Исправляем:
staticclass StreamInitializer {
public:
StreamInitializer ();
~StreamInitializer ();
} initializer; //Note object here in the header.
Здравствуйте, alzt, Вы писали:
A>Здравствуйте, slavo, Вы писали:
S>>singleton проблему решает, просто не хотелось постоянно дергать GetInstance. Но видно, никуда не деться. Сделал singleton.
A>А каким образом он решает проблему? Можно пример кода?
Наверное изначально я неправильно вопрос поставил. Нужно либо обеспечить создание объекта раньше какого-либо другого, либо обеспечить его существование при первом обращении к определенному набору функций. Singleton это решает, хотя и не совсем так, как хотелось. То, что я написал тоже не совсем похоже на singleton.
Здравствуйте, slavo, Вы писали:
S>День добрый, как гарантированно создать экземпляр класс CClass раньше, чем создастся экземпляр любого другого класса?
Есть способ — полностью отказаться от использования статических переменных, в т.ч. синглтонов, и управлять временем жизни объектов явно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, slavo, Вы писали:
S>>День добрый, как гарантированно создать экземпляр класс CClass раньше, чем создастся экземпляр любого другого класса?
R>Есть способ — полностью отказаться от использования статических переменных, в т.ч. синглтонов, и управлять временем жизни объектов явно.
Самый простой рецепт — собери все статические переменные и сделай их членами (НЕстатическими) одного класса. Часто такой класс называют Application или что-то в этом роде. Инициализироваться эти переменные будут строго в той последовательности, в которой они объявлены в классе. Экземпляр самого Application создается в основной функции приложения — в куче с помошью оператора new, или же прямо на стеке.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, slavo, Вы писали:
S>День добрый, как гарантированно создать экземпляр класс CClass раньше, чем создастся экземпляр любого другого класса?
1) Лучше бы так не делать вообще, так как трудно отлаживать и поддерживать. Если ты хочешь пользоваться своимм объектом из каких-то функций, которые могут быть вызваны слишком рано, то я бы советовал просто проверять в этих функциях, что объект уже инициализирован.
2) Если совсем никак не избежать (что сомнительно), то озвучь компилятор. У всех популярных компиляторов есть всякие непереносимые способы (например через специальные #pargma) указать, что этот объект надо создавать до остальных...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, rg45, Вы писали:
R>>Здравствуйте, slavo, Вы писали:
S>>>День добрый, как гарантированно создать экземпляр класс CClass раньше, чем создастся экземпляр любого другого класса?
R>>Есть способ — полностью отказаться от использования статических переменных, в т.ч. синглтонов, и управлять временем жизни объектов явно.
R>Самый простой рецепт — собери все статические переменные и сделай их членами (НЕстатическими) одного класса. Часто такой класс называют Application или что-то в этом роде. Инициализироваться эти переменные будут строго в той последовательности, в которой они объявлены в классе. Экземпляр самого Application создается в основной функции приложения — в куче с помошью оператора new, или же прямо на стеке.
Проблема в том, что я не могу трогать архитектуру. Надо работать с тем, что есть.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, slavo, Вы писали:
S>>День добрый, как гарантированно создать экземпляр класс CClass раньше, чем создастся экземпляр любого другого класса?
E>1) Лучше бы так не делать вообще, так как трудно отлаживать и поддерживать. Если ты хочешь пользоваться своимм объектом из каких-то функций, которые могут быть вызваны слишком рано, то я бы советовал просто проверять в этих функциях, что объект уже инициализирован.
Вот так я и сделал.
E>2) Если совсем никак не избежать (что сомнительно), то озвучь компилятор. У всех популярных компиляторов есть всякие непереносимые способы (например через специальные #pargma) указать, что этот объект надо создавать до остальных...
Это нельзя. Проект должен компиляться как минимум на MSVS6.0 и с помощью последней версии g++.
Здравствуйте, slavo, Вы писали:
S>Здравствуйте, rg45, Вы писали:
R>>Здравствуйте, rg45, Вы писали:
R>>>Здравствуйте, slavo, Вы писали:
S>>>>День добрый, как гарантированно создать экземпляр класс CClass раньше, чем создастся экземпляр любого другого класса?
R>>>Есть способ — полностью отказаться от использования статических переменных, в т.ч. синглтонов, и управлять временем жизни объектов явно.
R>>Самый простой рецепт — собери все статические переменные и сделай их членами (НЕстатическими) одного класса. Часто такой класс называют Application или что-то в этом роде. Инициализироваться эти переменные будут строго в той последовательности, в которой они объявлены в классе. Экземпляр самого Application создается в основной функции приложения — в куче с помошью оператора new, или же прямо на стеке.
S>Проблема в том, что я не могу трогать архитектуру. Надо работать с тем, что есть.
Плохо дело. Тогда могу предложить такой прием, может пригодится. Допустим есть две статические переменные, определенные в разных единицах трансляции. Пусть вторая переменная является зависимой от первой — т.е. при инициализации второй переменной используется первая. Например:
Порядок инициализации статических переменных, определенных в разных единицах трансляции неопределен. Нам же необходимо, чтобы переменная folder проинициализировалась раньше переменной path. Сделать это можно, если определения статических переменных спрятать внутри функций:
В данном примере статические переменные не были константами, поэтому функции возвращают ссылки на статические переменные, доступные таким образом для модификации. Это иллюстрирует адекватность замены статических переменных функциями, плюс детерминированный порядок инициализации.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Анатолий Широков, Вы писали:
АШ>Здравствуйте, Андрей Коростелев, Вы писали:
АК>>Идиома Schwarz Counter позволяет обеспечить гарантированный порядок инициализации объектов со static storage duration.
АШ>Только там откровенный ляп: АШ>
Здравствуйте, slavo, Вы писали:
S>Наверное изначально я неправильно вопрос поставил. Нужно либо обеспечить создание объекта раньше какого-либо другого, либо обеспечить его существование при первом обращении к определенному набору функций. Singleton это решает, хотя и не совсем так, как хотелось. То, что я написал тоже не совсем похоже на singleton.
1) А какая система у тебя? Я так понимаю, что бычно инициализация статических переменных происходит ещё до многопоточности. Поэтому ты скорее всего можешь выбросить из своего синглетона синхронизацию. Для этого достаточно где-то написать
const bool isCoreCreated = CCore::DoCreate();
2) Я так понимаю, что у тебя очень много статических объектов (иначе откуда возьмутся столь ранние вызовы твоих функций). Тогда наверное у тебя постепенно возниктнет много таких синглетонов. Соответсвенно порядок их инициализации, а возможно и её результат, станет трудноуправляемым и малопредсказуемым. Оно тебе надо?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, rg45, Вы писали:
R>>>>Есть способ — полностью отказаться от использования статических переменных, в т.ч. синглтонов, и управлять временем жизни объектов явно.
R>
R>...плюс детерминированный порядок инициализации.
Нифига он не детерминированный
Кроме того есть ещё и порядок разрушения...
Почему бы действительно ен управлять этим делом явно? Ведь в компиляторах обычно есть для этого средства!!!
Один фиг хорошее решение -- вообще избавится от зависимостей такого рода, не доступно... От чего бы не попросить компилятор о том, что тебе требуется прямо, а не через хаки какие-то?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, slavo, Вы писали:
E>>1) Лучше бы так не делать вообще, так как трудно отлаживать и поддерживать. Если ты хочешь пользоваться своимм объектом из каких-то функций, которые могут быть вызваны слишком рано, то я бы советовал просто проверять в этих функциях, что объект уже инициализирован.
S>Вот так я и сделал.
Насколько я понял, ты сделал не так.
E>>2) Если совсем никак не избежать (что сомнительно), то озвучь компилятор. У всех популярных компиляторов есть всякие непереносимые способы (например через специальные #pargma) указать, что этот объект надо создавать до остальных...
S>Это нельзя. Проект должен компиляться как минимум на MSVS6.0 и с помощью последней версии g++.
Ну и там и там таки есредства есть.
в одном нужно указать правильную секцию кода, а в другом приоритет создания.
Немного пошаманить с условной компиляцией и всё получится.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Немного пошаманить с условной компиляцией и всё получится.
В VC 6 это кажется называлось #pragma init_seg, или непосредственно надо было писать через #pragma comment( linker )
Про gcc сейчас не помню. Вспомню -- напишу, хотя может ещё кто помнит. Там можно было задавать приоритет создания объекта.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, slavo, Вы писали:
S>>Наверное изначально я неправильно вопрос поставил. Нужно либо обеспечить создание объекта раньше какого-либо другого, либо обеспечить его существование при первом обращении к определенному набору функций. Singleton это решает, хотя и не совсем так, как хотелось. То, что я написал тоже не совсем похоже на singleton.
E>1) А какая система у тебя? Я так понимаю, что бычно инициализация статических переменных происходит ещё до многопоточности. Поэтому ты скорее всего можешь выбросить из своего синглетона синхронизацию. Для этого достаточно где-то написать
const bool isCoreCreated = CCore::DoCreate();
Почему до многопоточности? Если у меня где-то есть объект А, который запускает поток, то разве это означает, что все статические объекты уже созданы? Нет. Я это проверил. Поэтому синхронизацию выбросить не получится.
E>2) Я так понимаю, что у тебя очень много статических объектов (иначе откуда возьмутся столь ранние вызовы твоих функций). Тогда наверное у тебя постепенно возниктнет много таких синглетонов. Соответсвенно порядок их инициализации, а возможно и её результат, станет трудноуправляемым и малопредсказуемым. Оно тебе надо?
Статических объектов тут много, но порядок их создания уже отлажен и проблем не возникает, поэтому они не будут переделываться на синглетоны. Если понадобится еще один такой объект (который мне нужен) и они оба захотят создаваться раньше друг друга, то тут и настанет конец мира .
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, Erop, Вы писали:
E>>Немного пошаманить с условной компиляцией и всё получится. E>В VC 6 это кажется называлось #pragma init_seg, или непосредственно надо было писать через #pragma comment( linker ) E>Про gcc сейчас не помню. Вспомню -- напишу, хотя может ещё кто помнит. Там можно было задавать приоритет создания объекта.
Информация полезная, но не хотелось бы привязывать проект (и без того мутный) к таким тонкостям .
slavo пишет: > День добрый, как гарантированно создать экземпляр класс CClass раньше, > чем создастся экземпляр любого другого класса? > Как создать объект раньше остальных? <message/2636970.aspx> Оценить
Здравствуйте, Кодт, Вы писали:
K>>>>>заюзать singleton. S>>>>а если не юзать singleton? А>>>А аргументы против этого метода имеются?
S>>Возможно будет медленнее работать из-за потерь на вход в критическую секцию и проверку флага создания.
К>А это уже измышления вокруг конкретной реализации конкретной разновидности синглетона.
Если да — то выкинь идею к чёрту.
Получится, что в условиях гонок объект конструируется дважды: один раз по полному пути, другой раз по сокращённому (члены конструируются, а тело — нет).
Здравствуйте.
Я не понимаю одну вещь
Как эта идиома позволяет обеспечить гарантированный порядок инициализации объектов со static storage duration в таком случае:
У меня есть class A:
// ----------- A.h ---------------
class A
{
public:
A(){};
~A();
}
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, rg45, Вы писали:
R>>...плюс детерминированный порядок инициализации. E>Нифига он не детерминированный
Время жизни статической переменной, объявленной внутри функции начинается при первом вызове функции — это по стандарту. Поэтому порядок инициализации, все-таки, детерминированный.
E>Кроме того есть ещё и порядок разрушения...
Если к этим переменным нет обращения в период разрушения статики (а мне думается, что в данном случае так и есть, пусть автор вопроса поправит, если я ошибаюсь), то неопределенность порядка разрушения не имеет никакого значения.
E>Почему бы действительно ен управлять этим делом явно? Ведь в компиляторах обычно есть для этого средства!!! E>Один фиг хорошее решение -- вообще избавится от зависимостей такого рода, не доступно... От чего бы не попросить компилятор о том, что тебе требуется прямо, а не через хаки какие-то?
Ну это у автора вопроса надо спрашивать, согласен ли он на зависимость от фич отдельных компиляторов.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
--
Не можешь достичь желаемого — пожелай достигнутого.