![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Alpher |
|
||||||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 5.2.2007 Репутация: нет Всего: нет |
Доброго времени суток, уважаемые!
Столкнулся со следующей проблемой и туплю уже пару дней: (те вещи, которые к делу не относятся, для краткости я опустил) Файл Singleton.h
Файл LibManager.h
Файл LibManager.cpp
Компилятор (MSVC8) выдает следующее: warning C4661: 'LibManager *Singleton<T>::_glob' : no suitable definition provided for explicit template instantiation request Ну и линкер, соответственно: error LNK2001: unresolved external symbol "protected: static class PlatformManager * PlatformManager::_glob" ..... Никак не могу понять, где косяк-то? Определение для _glob ведь присутствует... |
||||||
|
|||||||
| archimed7592 |
|
|||
![]() Архимед ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2531 Регистрация: 12.6.2004 Где: Moscow Репутация: 58 Всего: 93 |
не пойму че здесь написано
почему бы не сделать что-то типа
-------------------- If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas. © George Bernard Shaw |
|||
|
||||
| Alpher |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 5.2.2007 Репутация: нет Всего: нет |
Тут написано, что статическое поле _glob, унаследованное классом LibManager от шаблонного класса Singleton, являющееся указателем на LibManager равно нулю Только вот почему компилятор этого не замечает? P.S. С синтаксической точки зрения тут все ок Насчет
Это, конечно, вариант, но мне нужно будет в будущем: 1) подсчитывать ссылки и иметь возможность все-таки уничтожить экземпляр 2) наследовать от этого класса кучу других Это сообщение отредактировал(а) Alpher - 5.2.2007, 17:22 |
||||
|
|||||
| Любитель |
|
||||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Alpher, у тебя код честно говоря напоминает принцип - чтоб враг не понял.
По делу - почему в принципе инитить в ноль должен наследник??? Логичней вместо указателя иметь в предке протектед статик метод:
Инициализация будет выполнена при первом вызове метода (правило инициализация локальных статик-переменных). Добавлено @ 17:47 А то что ты хотел пишется так по идее:
Заметь - разные вещи. |
||||
|
|||||
| Alpher |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 5.2.2007 Репутация: нет Всего: нет |
Да, логичней. В случае, если наследник один. Если их много и статический указатель на экземпляр будет реализован в предке, то (как я понимаю, т.е. IMHO |
|||
|
||||
| Любитель |
|
||||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Пару примеров:
Где бы ты не инитил field он будет один и тот же!!!
A<B> и A<C> - два разных типа. У них будут два разных field. A - это вовсе не тип, это шаблон типа. У A<B> и B будет один field, потомучто B наследует от A<B>, но у A<C> и C - другой. |
||||
|
|||||
| Alpher |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 5.2.2007 Репутация: нет Всего: нет |
Виноват, совсем забыл, что родитель - шаблонный В общем, это - выход Но все же, почему же приведенная мной конструкция не собирается? (Уже из чисто спортивного интереса В рамках одного модуля - все ок, а когда подключаю к приложению - вопит линкер. Не понятно, почему он вопит, т.к. в самом приложении _glob не используется и приложению должно быть фиолетово, экспортируется оно или нет... |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Я выше писал - читай внимательно. Заметь, что LibraryManager и Singleton<LibraryManager> - два разных класса. И первый у тебя нигде явно не инстансируются, посему инит его полей (хотя стати поля у них и одни и те же) невозможен.
|
|||
|
||||
| Alpher |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 5.2.2007 Репутация: нет Всего: нет |
Сейчас попробовал: LibraryManager *LibraryManager::_glob = 0; и template<> LibraryManager *Singleton<LibraryManager>::_glob = 0; дают абсолютно одинаковые результаты (в смысле, тот же самый ворнинг при компиляции и те же ошибки при линковке) |
|||
|
||||
| Любитель |
|
|||
|
Программист-романтик ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 3645 Регистрация: 21.5.2005 Где: Воронеж Репутация: 24 Всего: 92 |
Не знаю тогда - без компилера не берусь гадать.
|
|||
|
||||
| Alpher |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 5.2.2007 Репутация: нет Всего: нет |
||||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
А вообще весьма любопытная концепция синглтона
Обычно смысл его в том, чтобы гарантировно обеспечить создание единственного экземпляра: второй просто создать невозможно. А у Вас при создании второго, а содать его можно, гарантированый вылет программы через assert при дебажной сборке и просто вылет при релизной. -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| Alpher |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 5.2.2007 Репутация: нет Всего: нет |
Конструктор/деструктор наследника пока висят в public для дебажных целей. Когда допишу класс, который будет собирать все синглтоны для использования приложением (и будет френдом для этих синглтонов), перенесу в protected Смысл моих мытарств заключается в том, чтобы централизованно создать экземпляры различных синглтонов, а потом их использовать из любого места программы через класс-ядро. Т.е. что-то вроде: Core::Inst().GetLibManager().doSomething(); Это сообщение отредактировал(а) Alpher - 5.2.2007, 19:45 |
|||
|
||||
| Vyacheslav |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 2124 Регистрация: 25.3.2002 Где: Москва Репутация: 9 Всего: 59 |
И что это даст?
То есть при разработке Вашей программы нужно всегда помнить о том, что прежде чем обратиться к чему либо, нужно проделать процедуру инициализации? Но тогда зачем это называть красивыми словом Singleton. Тогда проще класс с набором статических полей, проинициализировать их с помощью того же статического метода и обращаться к ним через теже статические методы. -------------------- С уважением, Вячеслав Ермолаев |
|||
|
||||
| Alpher |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 9 Регистрация: 5.2.2007 Репутация: нет Всего: нет |
Не совсем так. Красивое слово Singleton было выбрано, т.к. оно короче, чем PseudoSingleton Инициализация экземпляров происходит единовременно при инициализации класса-ядра. Пользователь может обращаться к ним только через Core::Inst().getЧтоНибудь().doЧтоНибудь() или ЧтоНибудьКласс::Inst().doЧтоНибудь() Насчет статических полей и методов: В случае одного уровня наследования это действительно было бы проще и удобней. В моем случае требуется, грубо говоря, обеспечить возможность наследовать от производных (по отношению к Singleton) классов еще какие-либо, причем совершенно произвольно. Т.е., скажем: class LibManager : public Singleton<LibManager> class PluginManager : public LibManager, public PluginFunctions class RichPluginManager : public PluginManager, public CoolFunctions и т.п. Сомневаюсь, что в случае со статическими полями и методами в LibManager это было бы удобно. Городить темплейты на все и вся, как мне кажется, здесь нецелесообразно. Потом, в Т.З. указана возможность наращивания функционала, т.е. появления каких-либо не предусмотренных сейчас классов. В моем случае нужно перегрузить только Inst() и Ref(), а также определить _glob. P.S. Согласен, без определения _glob в потомках можно обойтись Добавлено @ 21:36 Кстати, нашел причину первоначальной проблемы Банально, в хедере, где определяется _UT_EXPORT была опечатка и оно компилилось как __declspec(dllimport) Сейчас конструкция, приведенная в первом посте отлично работает. Это сообщение отредактировал(а) Alpher - 5.2.2007, 21:29 |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |