![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| d06osipov |
|
||||||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 1.11.2006 Репутация: нет Всего: нет |
Есть шаблонный класс A<T> (синглетон). Есть другой класс B<T> (тоже синглетон). Мне нужно специализировать B<T> для всех типов, для которых A<T> специализирован. Напрашивается такое решение:
Но это не прокатывает, так как вызов B<T>::inst() влечёт вызов конструктора B (если B ещё не создан), а конcтруктор B в свою очередь использует класс A, поэтому вызывается снова конструктор класса A (который тоже синглетон) --- второй раз для того же объекта. Но на этом не заканчивается --- A снова использует B, который не инициализирован полностью, вызывая конструктор. Получается бесконечная рекурсивная инициализация. Напрашивается решение:
Но это не проходит, так как компилятор, как выяснилось специализирует только статическую функцию, но не сам класс. Ещё вариант:
Это не годиться, так как функция A<T>::neverCall может не специализироваться. Я делаю так:
Это работает, но я опасаюсь, что класс B может удалиться раньше, чем A, а это может привести к сигфолту. Скажите, есть какой-нибудь Стандартный, надёжный способ? |
||||||||
|
|||||||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
не совсем понял
нужно специализировать или инстанциировать? |
|||
|
||||
| d06osipov |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 1.11.2006 Репутация: нет Всего: нет |
Пример: у меня в программе используется класс A<int>.
Мне нужно, чтобы C++ автоматически специализировал класс B<int> в таком случае. (и это не бессмысленно: так как B<T> синглетон, его конструктор будет вызван до main(), в том случае, если этот класс вообще существует, то есть специализирован, а это мне и надо. Больше от класса B мне ничего не требуется, кроме вызова конструктора до main()) Это сообщение отредактировал(а) d06osipov - 5.6.2008, 11:40 |
|||
|
||||
| Alek86 |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
если инстанцировать, то рекомендую прочесть Главу 10 книги
Вандевурд, Джосаттис - Шаблоны C++ если нету но хочется, могу подсказать, где взять - обращайся в личку Добавлено @ 11:44 могу и ошибаться, но это, вроде, называется инстанцирование по требованию если ошибаюсь, то глава 10 той книги тебе вряд-ли поможет Добавлено @ 11:48 может, поможет
Это сообщение отредактировал(а) Alek86 - 5.6.2008, 11:52 |
||||||
|
|||||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
||||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
кажись, у тебя неправильно организован синглтон у синглтона должен быть закрытый или защищенный конструктор, чтобы никто кроме него самого не мог его создать. А остальные могут получать экземпляр синглтона только через статический GetInstance |
|||
|
||||
| d06osipov |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 1.11.2006 Репутация: нет Всего: нет |
Да, но в синглетонах Мейерса (какие я использую), если объект ещё не инициализирован и происходит Instance, то он создаётся, а значит вызывается конструктор. То есть конструктор неявно вызывается через функцию inst(). |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
так во всех синглетонах вызывается только свой конструктор - конструкторы остальных синглетонов недоступны |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
угу...
а все же в чем задача? к примеру это насколько я знаю, неправильно если у тебя там new используется, то объект создастся во время работы inst() если же статический объект, то ему можно вообще не создаваться, если функция inst() не будет вызвана это называется "отложенная инициализация", кажется |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
если у тебя один синглетон для создания своей инстанции требует инстанцию другого синглетона, которая в свою очередь требует первую - значит что то в проектировке программы не верно .. (аж язык поломался от закрутки - бедный компилятор что ему приходится читать
|
|||
|
||||
| d06osipov |
|
|||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 1.11.2006 Репутация: нет Всего: нет |
Нет. Один синглтон требует инициализации другого. Это верно. Но другой не требует инициализации первого. Он должен лишь гарантировать специализацию первого.
Добавлено через 9 минут и 3 секунды Я использую два вида синглтонов. Первый вид --- такой, как в Boost::singleton. Он гарантирует инициализацию до main. Второй --- синглетон Мейерса. Он гарантирует инициализацию при первом использовании. Если синглтоны первого типа используют только синглтоны второго, то коллизий произойти не может (второй тип инициализируется при обращении). Такое использование мне и требуется. A<T> --- второго типа. Его объект может вообще не создаваться в процессе работы программы, но он специализирован для всех типов, которые нужны. Конструктор B<T> содержит важный код, который должен быть выполнен прежде всего, но B<T>. B<T> синглтон первого типа, поэтому его конструктор автоматически вызовется до main, но B<T> нигде не упоминается в программе, а поэтому компилятор не специализирует его. |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
синглетон не гарантирует специализацию .. или мы расходимся в трактовке понятия - нельзя ли уточнить что подразумевается с вашей точки зрения ? |
|||
|
||||
| d06osipov |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 1.11.2006 Репутация: нет Всего: нет |
Совершенно верно. В этом и проблема. Пользователь пишет у себя в коде A<int>::inst(). Он и понятия не имеет про B<T>; и я не могу заставлять его знать про B<T>. Поэтому нигде в программе не употребляется B<int> (только A<int>), но мне надо, чтобы такой класс существовал. А если бы он существовал, то был бы синглтоном, и конструктор выполнился бы до main --- то что мне требуется (иными словами, мне надо до main() выполнить код, зависящий от T для всех типов T, для которых есть A<T>). Я думал так: если A<T> существует, компилятор обязан специализировать два метода: конструктор и деструктор. Если, например, в конструкторе A<T> я обращусь к объекту B<T>, то значит, компилятору придётся специализировать B<T> (он используется в существующей функции). Но возникла проблема с рекурсивной инициализацией. Если поместить в деструктор --- может возникнуть проблема с обращением к уничтоженному объекту. А конструктор и деструктор это единственные два метода про которые наверняка известно, что они специализируются. Вот я думаю, может так можно:
Здесь используется тип B<T>, но ничего не вызывается. Я опасаюсь компилятор может повести себя так: "я размер узнал, больше мне этот класс не нужен, не буду специализировать".
Вот что: компилятор специализирует класс A для типа T, значит в откомпилированной программе существует тип A<T>. Это означает, что существует код хотя бы для одной нестатической функции A<T>::f, выделена память для всех статических членов в сегменте. На первый взгляд может показаться, нет никакой разницы между специализированным классом и нет. Начинающие даже, наверное думают, что есть классы A<T> для всех типов T. Но когда в ход идут трюки с Синглетонами --- тут очень большая разница, специализирован тип, или нет. Это сообщение отредактировал(а) d06osipov - 5.6.2008, 15:49 |
||||
|
|||||
| Alek86 |
|
||||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
думаю, немногие поняли, что тебе все же нужно я тоже не понял и похоже ты до сих пор путаешь специализацию и инстанцирование может это поможет? затайпдефить один синглтон в другом?
хотя не совсем уверен, что компилер обязан инстанцировать этот тайпдеф, если он нигде не используется Добавлено @ 16:07 колмпилятор не специализирует, а инстанцирует инстанциация - когда компилер встречает строчку типа C<int>, смотрит, что такого типа еще нет, и по шаблону класса C создает тип C<int> специализация - это когда у тебя есть шаблонный класс.
потом ты понимаешь, что для типа int можно сделать намного более удобную реализацию:
вот то что ты дописал - это специализация Это сообщение отредактировал(а) Alek86 - 5.6.2008, 16:08 |
||||||
|
|||||||
| d06osipov |
|
||||
|
Шустрый ![]() Профиль Группа: Участник Сообщений: 72 Регистрация: 1.11.2006 Репутация: нет Всего: нет |
Нет, вы правильно меня поняли. Я тоже думал, что тайпдеф прокатит, ан нет. Компилятор умный (g++), он этот тайпдеф видит, но класс не специализирует (дествительно, этот тайпдеф по идее вообще никак на объектный файл не должен влиять. Так и происходит). Я пробовал указатели на него делать, но лишнюю работу g++ на себя брать не хочет. Это сообщение отредактировал(а) d06osipov - 5.6.2008, 16:12 |
||||
|
|||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |